별로 어렵지 않은 문제였다.

 

다만 코틀린스럽게 풀지는 못했다...

내가 제출한 코드

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()로 맞춰줍니다.

 

끄읕

+ Recent posts