별로 어렵지 않은 문제였다.
다만 코틀린스럽게 풀지는 못했다...
내가 제출한 코드
class Solution {
fun solution(numbers: IntArray): IntArray {
var answer: IntArray = intArrayOf()
var intset = mutableSetOf<Int>()
for(i in 0 until numbers.size - 1) {
for(j in i+1 until numbers.size) {
intset.add(numbers[i] + numbers[j])
}
}
answer = intset.sorted().toIntArray()
return answer
}
}
이중for문을 이용해서 더해주었고 원소가 중복되면 안되기에 Set를 사용했다.
내 생각 코틀린스럽게 푼 사람 (사실 코틀린스럽다는 말을 정확히 몰라 틀릴 수 있음,,)
뭔가 코틀린 함수 쓴게 코틀린스러운건가,,ㅎㅎ
다른 분의 코드
class Solution {
fun solution(numbers: IntArray): IntArray {
val list = numbers.toList()
return list.withIndex().flatMap { i -> list.withIndex().map { j -> i to j } }
.filter { it.first.index != it.second.index }
.map { it.first.value + it.second.value }
.toSortedSet()
.toIntArray()
}
}
분석해보면 공부에 도움이 될거 같아 분석한번 해보겠습니다.
분석에 앞서 필요한 확장함수를 조금 알아보고 가자.
.withIndex() -> 객체의 원소를 (index, value) 형태로 접근할 수 있게 해준다.
예) list = listOf("a", "b", "c")
indexedList = list.withIndex()
print(indexedList)
[IndexedValue(index=0, value=a), **IndexedValue(index=1, value=b)**, IndexedValue(index=2, value=c)]
이런식으로 출력된다.
.flatMap -> 컬렉션 안에 컬렉션이 있을 경우 내부 컬렉션을 펼쳐주는 연산이며 .map과 다르게 1대1매핑이 아닌 1대 多 매핑이 가능하다. 즉 모든 요소들의 생성값을 다룰 수 있다.
.filter -> 간단히 필터 조건문안에 조건을 만족하는 원소들만 받아서 가져오겠다는거다.
이제 코드를 하나하나 뜯어보자. (너무 깊숙이 뜯진 못한다,,)
val list = numbers.toList()
numbers를 리스트 형태로 바꾸어 list에 담아준다.
list.withIndex().flatMap { i -> list.withIndex().map { j -> i to j } }
이 부분이 이해하기 굉장히 어려웠던 부분이었다. 사실 완벽하게 이해한 것인지는 모르나 틀렸을 경우 댓글부탁드립니다.
우선 문제의 첫 번째 입출력 예인 [2,1,3,4,1] 을 입력값으로 해서 예시로 사용해보겠다.
withIndex() 를 통해 [(0,2) (1,1) (2,3) (3,4) (4,1)] 이런식의 원소의 인덱스와 실제 value가 포함된리스트가 반환된다.
flatMap() 을 통해 이 안에 원소들을 1대 다 매핑이 가능하게 만들어줌과 동시에 마지막엔 싱글리스트로 반환해준다.
.map{} 안에 "i to j"는 i와 j를 pair시켜주는 역할이다.
[(0,2) (1,1) (2,3) (3,4) (4,1)] 이 리스트의 i로 돌아가는 반복문과 list.withIndex().map의 j 인덱스로 돌아가는 반복문으로
j가 i를 기준으로 각 원소를 순회하며 i to j를 실행한다. 가독성을 위해 많은 띄어쓰기를 넣었습니다...
[(0,2) (0,2) , (0,2) (1,1) , (0,2) (2,3) , (0,2) (3,4) , (0,2) (4,1)]
마찬가지로 다음 i 원소인 (1,1)을 기준으로 실행
[ (1,1) (0,2) , (1,1) (1,1) , (1,1) (2,3) , (1,1) (3,4) , (1,1) (4,1)]
이런식으로 하면 반복하면
[(0,2) (0,2) , (0,2) (1,1) , (0,2) (2,3) , (0,2) (3,4) , (0,2) (4,1)
(1,1) (0,2) , (1,1) (1,1) , (1,1) (2,3) , (1,1) (3,4) , (1,1) (4,1)
(2,3) (0,2) , (2,3) (1,1) , (2,3) (2,3) , (2,3) (3,4) , (2,3) (4,1)
(3,4) (0,2) , (3,4) (1,1) , (3,4) (2,3) , (3,4) (3,4) , (3,4) (4,1)
(4,1) (0,2) , (4,1) (1,1) , (4,1) (2,3) , (4,1) (3,4) , (4,1) (4,1)]
이런식의 리스트가 반환됩니다.
.filter { it.first.index != it.second.index }
서로 다른 인덱스의 있는 두 수를 더해주기 위해서는 이 리스트에서 filter를 통해 (0,2)(0,2) , (1,1)(1,1) , (2,3)(2,3) , (3,4) (3,4) , (4,1)(4,1) 과 같은 인덱스 값이 같은 원소들을 제외하고 인덱스 값이 다른 원소들만 걸러줍니다.
[ , (0,2) (1,1) , (0,2) (2,3) , (0,2) (3,4) , (0,2) (4,1)
(1,1) (0,2) , , (1,1) (2,3) , (1,1) (3,4) , (1,1) (4,1)
(2,3) (0,2) , (2,3) (1,1) , , (2,3) (3,4) , (2,3) (4,1)
(3,4) (0,2) , (3,4) (1,1) , (3,4) (2,3) , , (3,4) (4,1)
(4,1) (0,2) , (4,1) (1,1) , (4,1) (2,3) , (4,1) (3,4) , ]
.map { it.first.value + it.second.value }
원소들의 value 를 합해준 리스트를 반환합니다.
[3, 5, 6, 3,
3, 4, 5, 2,
5, 4, 7, 4,
6, 5, 7, 5,
3, 2, 4, 5]
.toSortedSet()
Set 컬렉션의 가장 큰 특징인게 중복된 원소가 없는 없다는것입니다.
toSortedSet() 으로 set 컬렉션형태로 바꾸고 오름차순으로 정렬해줍니다.
그리고 마지막은 반환형태에 맞게 toIntArray()로 맞춰줍니다.
끄읕