정방향 요구르트와 reverse 요구르트
2574. Left and Right Sum Differences
문제 설명
- 숫자 배열이 주어진다.
- left에서부터 sum을 계산한 배열, right에서부터 sum을 계산한 배열을 구해준다. (여기서 sum을 계산했다는 거는 index=i일때, leftArray[i]란 nums배열의 [i] 이전까지를 계산한 값을 의미한다.
- 그리고 그 배열에서 left,right배열 각각의 인덱스의 차를 구한 배열을 return
문제 풀이
- 문제 자체는 쉽긴한데, 여기애서
reversed()
와reverse()
의 차이를 좀 더 정리하는 기회가 될 것 같아서 이 문제를 포스팅해봤다.- 일단 문제는 그냥
leftSum
,rightSum
으로 합계를 저장할 변수를 선언해주고 right는 원본배열에서 reverse한채로 수행해주면된다.
최종 제출 코드
class Solution {
func leftRightDifference(_ nums: [Int]) -> [Int] {
let leftnums = nums
let rightnums = Array(nums.reversed())
var leftAnswer = [0]
var leftSum = 0
var rightAnswer = [0]
var rightSum = 0
for i in 0 ..< nums.count - 1 {
leftSum += leftnums[i]
rightSum += rightnums[i]
leftAnswer.append(leftSum)
rightAnswer.append(rightSum)
}
rightAnswer.reverse()
var answer = [Int]()
for i in 0 ..< nums.count {
answer.append(abs(leftAnswer[i] - rightAnswer[i]))
}
return answer
}
}
reversed() vs reverse()
이 문제를 풀면서 reverse 사용시 요상했던 점들이 있었다. 일단 reversed()를 했을 때 왜 [i]를 통해서 인덱스 접근이 불가능한가 ? 타입은 무슨 타입인가 ? 부터해서 요상한 경험을 했어서 이를 좀 정리를 해봤다.
먼저 reversed()는 뭐로 출력이 되는가 ?
ReversedCollection<Array<Int>>(_base: [10, 4, 8, 3])
reversed()
는 왜 인덱스 접근이 왜 안되는거?코드를 보니 var rightnums = Array(nums.reversed())
라는 부분이 눈에 띕니다. 여기서 nums.reversed()
만 쓰면 rightnums[i]
처럼 인덱스로 접근하려 할 때 오류가 납니다. 이유는 간단합니다: reversed()
는 배열을 직접 뒤집어서 새로운 배열을 만들어낸게 아니라, ReversedCollection이라는 래퍼 타입을 반환한거라고 한다.
그럼 래퍼타입이 뭔데 ??
어떤 데이터나 객체를 감싸서(Wrap 은박지 래핑할때 그거 맞다) 추가적인 기능이나 다른 인터페이스를 제공하는 타입.
그니까 원래 데이터를 직접 건드리는게 아니라 그 위에 얇은 껍데기를 씌워서 VIEW만 제공한다고 생각하면 된다!
안경쓰면 잘보이긴하는데, 그렇다고 내 눈을 건드리는 거랑은 다른 거? (비유가 이게 맞나 모르겠는데 느낌을 봐주시면 될 것 같다.)
그래서 새로운애를 창조하는게 아니라 메모리 효율성은 좋지만, 인덱스에 접근하는거는 따로 이걸 실체로 만들어줘야하는 것이다.
그 해결책 중 하나가 코드에서 썼던 것처럼 Array()
로 감싼 것! 이러면 새롭게 배열을 생성한것으로 판정이 되니까 더 이상 VIEW를 제공하는 콜렉션 타입에서 벗어나서 엄연한 배열로서 접근이 가능해지는 것! (메모리에 새로 할당을 해주는 것이다. 메모리 할당이 되니까 접근을 할 수 있는거다)
해석 : 컬렉션의 요소를 역순으로 표현하는 뷰를 반환합니다.
reverse()
와의 차이는?반면, reverse()
는 배열 자체, 즉 원본을 그냥 그대로 뒤집어 버리는 것이다.
새로운 객체를 만드는 게 아니라 원래 배열 순서 자체가 뒤집어지니까 당연히 접근이 가능하다. 기존에 있던 배열의 메모리를 그대로 대체한 것이라고 보면 될 것!
var arr = [1, 2, 3]
arr.reverse() // arr는 이제 [3, 2, 1]
요약
reversed()
는 원본을 건드리지 않고 그냥 그렇게보이는 VIEW를 제공reverse()
는 원본을 직접 수정한다
reversed()
: 원본 유지,ReversedCollection
이라는 타입을 반환 -> 인덱스로 접근하려면Array()
로 변환 필요.reverse()
: 원본을 직접 뒤집음, 반환값 없음.