개발노트/Kotlin

내일배움캠프 3주차 1일 코틀린 심화-알고리즘문제

시계속세상은아직돌아가는중 2023. 7. 24. 19:57

알고리즘 문제 : 프로그래머스 최빈값 구하기

https://school.programmers.co.kr/learn/courses/30/lessons/120812

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

class Solution {
    fun solution(array: Array<Int>): Int {
        var frequency = mutableMapOf<Int, Int>()

        var maxFre:Int = 0 // 11
        var answer: Int = array[0]

        for(num in array){
            var nowNumberFrequency = frequency.getOrDefault(num , 0)+1


            if (nowNumberFrequency > maxFre){
                maxFre = nowNumberFrequency
                answer = num
            }else if (nowNumberFrequency == maxFre){
                answer = -1
            }

        }

        return answer
    }
}

fun main(){
    var  solution = Solution()
    var array = arrayOf( 1,1 ,2, 2,2,3,3)
    var answer = solution.solution(array)

    println("$answer")
}

해당 코드는 오류가 났다.

for문으로 돌아가는 결과값을 저장해주는 선언이 없으므로 당연한 결과였다.

class Solution {
    fun solution(array: Array<Int>): Int {
        var frequency = mutableMapOf<Int, Int>()

        var maxFre:Int = 0 // 11
        var answer: Int = array[0]

        for(num in array){
            var nowNumberFrequency = frequency.getOrDefault(num , 0)+1
            frequency[num] = nowNumberFrequency

            if (nowNumberFrequency > maxFre){
                maxFre = nowNumberFrequency
                answer = num
            }else if (nowNumberFrequency == maxFre){
                answer = -1
            }

        }

        return answer
    }
}

fun main(){
    var  solution = Solution()
    var array = arrayOf( 1,1 ,2, 2,2,3,3)
    var answer = solution.solution(array)

    println("$answer")
}

으로 해결하였다.

frequency[num] = nowNumberFrequency

덕분에 frequency key값 num에 nowNumberFrequency으로 나온 값이 밸류로 저장된다.

 

해당 문제의 알고리즘을 고민하면서  map기능에 대한 이해에 상당히 많은 시간을 투자하였다.

 

해당 코드의 map탐색을 임의의 정렬 array와 함께 표로 정리하자면

 

num nowNumpre maxPre
1 1 1
1 2 2
2 1 2
2 2 2
2 3 3
3 1 3
3 2 3

이므로, answer = 2를 반환한다.

 

여기서 코틀린에서 새로 사용하게 된 개념이 있다.

var nowNumberFrequency = frequency.getOrDefault(num , 0)+1

이 변수는 frequency의 디폴트 밸류값을 반환한 다음에 +1을 더하는 구문이다.

(num : key , 0 : defalutValue),  

var frequency = mutableMapOf<Int, Int>()

내가 선언한 key값과 value값 둘 다 int형으로 받도록 선언되었기 때문에 nowNumberFrequency는 int형 변수가 된다.

key값은 임의의 배열의 모든 요소가 돌아가면서 배치되며, 배치될 때 마다 해당 숫자의 디폴트값에 1이 더해진다.

 

그렇다면 여기서 value의 값은 해당 숫자가 얼마나 많이 등장한지에 대한 횟수와 같아진다.

(디폴트 밸류 0에서 +1씩 상승한다 = 그 만큼 해당 key값이 등장했다) 

 

임의의 배열

var array = arrayOf( 1,1,2)

로 예를 들자면,

 

key 값 1 value 값 1(0+1)

key 값 1 value 값 2(1+1)

key 값 1 value 값 1(0+1)

 

이된다

 

또한 임의의 배열 array의 모든 요소를 탐방하는 for문

for(num in array)

덕분에 frequency의 키값에는 배열의 요소들이 들어간다.

 

따라서 이 코드를 돌릴 때 마다 위의 표처럼 작동되며, 이는 배열의 정렬과 상관 없는 수치이다.

 

임의의 배열

var array = arrayOf( 1,2,3,1,2,3,4,3)

가 들어간다고 쳤을 때 맵의 형태는

1 : 1

1: 1 , 2 : 1

1 : 1 , 2 : 1 , 3 : 1

1: 2, 2 : 1 , 3 : 1

1: 2 , 2: 2 , 3: 1

1: 2 , 2:2, 3: 2

1 : 2, 2: 2, 3: 2, 4 : 1

1: 2, 2: 2, 3: 3 , 4: 1

 

이렇게 작동하기 때문이다.

위의 표처럼 정리했을 때는

num  nowNumFre maxFre answer
1 1 1 1
2 1 1 -1
3 1 1 -1
1 2 2 1
2 2 2 -1
3 2 2 -1
4 1 2 -1
3 3 3 3

이 된다.

 

 

2. 문제 해결을 위한 브레이크 포인트와 디버깅

해당 화면에서 튜터님께 자문을 구한 결과, 문제가 될 것이라고 예측되었던 13번째줄을에 브레이킹 포인트를 찍고 디버깅을 하였다

13줄 옆을 클릭하여 붉은색 점을 찍고 재생 버튼이 아닌 벌레모양(디버깅)을 클릭하여 나온 결과값

에서 이 코드를 계속 돌릴려면 

파란색 동그라미 친 부분을 눌러 코드가 계속 진행하도록 한다.

해당 디버깅 덕분에 변수들에 제대로 값이 들어가지 않음을 확인했고, 이는 for문이 돌았을 때 저장하는 map이 없어서 그런 것으로 판명되었다.