문제에서 정의한 튜플의 성질은 아래와 같다.
1. 중복된 원소가 있을 수 있습니다. ex: (2,3,1,2)
2. 원소에 정해진 순서가 있으며, 원소의 순서가 다르면 서로 다른 튜플입니다. ex:(1,2,3) != (1,3,2)
3. 튜플의 원소 개수는 유한합니다.
위의 조건에 맞춰서 구현을 진행하면 된다. 필자가 진행한 알고리즘의 순서는 아래와 같다.
1. 맨 앞, 맨 뒤의 '{' '}' 를 제거한다. => removePrefix, removeSuffix 를 이용
2. 코틀린 extension을 이용하여 새로운 split() 를 만든다.
- 반복문을 진행하면서 각각의 원소에 있는 '{', '}' 를 제거하며 반환할 리스트에 추가한다.
- 만들어진 리스트를 원소의 길이를 대상으로 오름차순으로 정렬을 진행한다.
3. 2번 과정에서 만들어진 리스트의 값들을 순회하면서 split(",")를 진행하고 나눠진 원소들을 Set에 넣는다.
소스 코드를 보면 이해가 가능하다.
fun solution1(s: String): IntArray {
return s.substring(2, s.length - 2)
.split("},{")
.asSequence()
.map {
it.split(",").map {
it.toInt()
}
}
.toList()
.sortedBy { it.size }
.fold(setOf<Int>()) { acc, list ->
acc.union(list)
}.toIntArray()
}
split("},{")로 나눈 것과 fold의 초기값이 항상 int가 아닌 다른 자료형이 들어간다는 것이 충격적이였다.
class Solution {
fun solution(s: String): IntArray {
val set = mutableSetOf<Int>()
s.removePrefix("{")
.removeSuffix("}")
.split()
.forEach {
it.split(",").forEach {
set.add(it.toInt())
}
}
return set.toTypedArray().toIntArray()
}
private fun String.split(): List<String> {
val list = mutableListOf<String>()
var startIndex = 0
var endIndex = -1
while (++endIndex < this.length) {
if (this[endIndex] == '}') {
list.add(
this.substring(startIndex, endIndex)
.removeSuffix("}").removePrefix("{")
)
startIndex = endIndex + 2
}
}
list.sortBy { it.length }
return list.toList()
}
}