일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 2022 플러터 안드로이드 스튜디오
- rxjava cold observable
- 스택 큐 차이
- android retrofit login
- 서비스 vs 쓰레드
- 서비스 쓰레드 차이
- 자바 다형성
- 멤버변수
- 클래스
- 큐 자바 코드
- 안드로이드 라이선스
- jvm이란
- 안드로이드 유닛 테스트
- 안드로이드 os 구조
- 플러터 설치 2022
- 스택 자바 코드
- android ar 개발
- 안드로이드 레트로핏 crud
- Rxjava Observable
- 안드로이드 레트로핏 사용법
- ANR이란
- 안드로이드 라이선스 종류
- rxjava hot observable
- rxjava disposable
- 안드로이드 유닛테스트란
- 2022 플러터 설치
- jvm 작동 원리
- ar vr 차이
- 객체
- 안드로이드 유닛 테스트 예시
- Today
- Total
나만을 위한 블로그
[Algorithm] 프로그래머스 - 최빈값 구하기 (Kotlin) 본문
최빈값은 주어진 값 중에서 가장 자주 나오는 값을 말한다. 정수 배열 array가 매개변수로 주어질 때 최빈값을 리턴하도록 solution()을 완성하라. 최빈값이 여러 개면 -1을 리턴한다
처음에 접근한 방법은 리스트를 돌면서 리스트 안의 요소들을 비교한 다음 겹치는 걸 출력하는 방식이었다. 여러 개가 나올 경우에 대한 예외처리를 짜던 중 코드가 많이 더러워지고 내가 원하는 결과가 나오지 않아서 다른 사람의 풀이를 확인해봤다.
class Solution {
fun solution(array: IntArray): Int {
val list = array.groupBy { it }.entries.sortedByDescending { (key, value) -> value.size }
return if (list.size > 1 && list[0].value.size == list[1].value.size) -1 else list[0].key
}
}
파이썬만큼은 아니겠지만 코틀린도 너무 간결하다. 잘 사용하지 않았던 키워드와 함수가 있어서 각각을 확인해봤다. 먼저 groupBy {}다.
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/group-by.html
각 요소에 적용된 지정된 keySelector 함수에서 반환된 키로 원래 배열의 요소를 그룹화하고, 각 그룹 키가 해당 요소 목록과 연결된 맵을 반환한다. 반환된 맵은 원래 배열에서 생성된 키의 항목 반복 순서를 유지한다
컬렉션에 붙여서 사용하면 컬렉션 안의 데이터들을 일정 기준으로 그룹화해서 Map 형태로 반환하는 함수다. 이 때 일정 기준이란 groupBy 뒤의 중괄호 블럭 안에 넣는 조건이다.
아래는 위 링크에서 제공하는 groupBy의 예제 코드 스니펫이다.
val words = listOf("a", "abc", "ab", "def", "abcd")
val byLength = words.groupBy { it.length }
println(byLength.keys) // [1, 3, 2, 4]
println(byLength.values) // [[a], [abc, def], [ab], [abcd]]
val mutableByLength: MutableMap<Int, MutableList<String>> = words.groupByTo(mutableMapOf()) { it.length }
// same content as in byLength map, but the map is mutable
// byLength 맵과 동일한 내용이지만 Map은 변경 가능하다
println("mutableByLength == byLength is ${mutableByLength == byLength}") // true
groupBy {} 안에 "it.length" 라는 조건을 넣었다. 문자열 길이를 기준으로 Map을 만들겠다는 뜻이다.
그래서 byLength를 출력하면 아래와 같이 출력된다.
val words = listOf("a", "abc", "ab", "def", "abcd")
val byLength = words.groupBy { it.length }
println(byLength)
// {1=[a], 3=[abc, def], 2=[ab], 4=[abcd]}
다시 정답 코드로 돌아간다. 내가 좀 더 보기 편하게 코드를 조금 바꿨다.
val list = array.groupBy { it }
.entries.sortedByDescending { (key, value) ->
value.size
}
val a = if (list.size > 1 && list[0].value.size == list[1].value.size) {
-1
} else {
list[0].key
}
그 다음 entries 키워드를 사용하고 sortedByDescending {}을 사용하고 있다.
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-map/entries.html
이 Map에 있는 모든 키밸류 쌍의 읽기 전용 Set를 반환한다
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/sorted-by-descending.html
지정된 선택기 함수(selector function)에서 반환된 값의 자연 정렬 순서에 따라 내림차순으로 정렬된 모든 요소 목록을 반환한다. 정렬이 안정적이다. 이는 동일한 요소가 정렬 후 서로 상대적인 순서를 유지함을 의미한다
groupBy {}로 만들어진 Map을 Set으로 반환한다. 그리고 해당 Set에서 리턴하는 값을 정렬한다는데 이 부분은 잘 모르겠어서 정답 코드 안의 sortedByDescending {} 안에 key, value를 각각 출력시켜서 확인해봤다.
??? 대체 어떻게 작동하는 건지 모르겠다. 그래도 Descending이 붙었다면 큰 숫자부터 작은 순서대로 정렬하는 것일테니 1을 하나 더 넣어서 실행시켜봤다.
3은 세 개, 1은 2개, 2와 4는 각 1개씩 있으니 정렬이 잘 된 것을 볼 수 있다.
entries가 Set이기 때문에 sortedByDescending {} 안에 (key, value)를 조건으로 넣고, value인 Map의 크기에 따라서 정렬된다.
그 다음 if로 조건을 걸어서, 리스트에 데이터가 2개 이상인지 확인하고 첫 번째와 두 번째 Map에 담긴 값의 크기가 같다면 -1, 아니면 첫 번째 Map의 key를 리턴한다. value는 위 사진에서 보다시피 Map 형태라서 value를 사용하면 문제의 입출력 예시와 다른 값을 리턴하게 되기 때문에 사용하면 안 된다.
val a = if (list.size > 1 && list[0].value.size == list[1].value.size) {
-1
} else {
list[0].key
}
2개 이상인지 확인하는 건 문제에서 요구했던 "최빈값이 여러 개면 -1을 리턴한다"를 위해서라고 생각된다.
리스트 크기를 확인하는 부분을 없애면 같은 숫자를 2개 이상 넣고 실행했을 때 에러가 발생한다.
'알고리즘 문제 풀이 > 프로그래머스' 카테고리의 다른 글
[Algorithm] 프로그래머스 - 피자 나눠 먹기(3) (Kotlin) (0) | 2022.12.21 |
---|---|
[Algorithm] 프로그래머스 - 피자 나눠 먹기(2) (Kotlin) (0) | 2022.12.21 |
[Algorithm] 프로그래머스 - 피자 나눠 먹기(1) (Kotlin) (0) | 2022.12.21 |
[Algorithm] 프로그래머스 - 짝수는 싫어요 (Kotlin) (0) | 2022.12.20 |
[Algorithm] 프로그래머스 - 분수의 덧셈 (Kotlin) (0) | 2022.12.16 |