ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [프로그래머스][Kotlin] 억억단을 외우자
    프로그래머스 2023. 2. 16. 18:40
    728x90

    최근에 푼 문제중에 시간 초과 때문에 가장 고민하면서 풀었던 문제였던것 같습니다.
    처음에는 하기 코드를 보시면 알겠지만 숫자별로 나온 횟수를 countList에 저장하여
    인덱스별로 인덱스와 같은 숫자가 나온만큼 횟수를 저장하여 하였었으나 시간초과가 나와 통과를 할 수 없었습니다.
    하기 코드를 이용하여 통과할 수 있는 실력이 안되어 통과를 못한 것일 수도 있습니다.

    // 시간 초과 코드
    class Solution {
        fun solution(e: Int, starts: IntArray): IntArray {
            var answer: IntArray = intArrayOf()
            var countList = MutableList(e+1){ 0 }
            var check = 1
            var temp : Int
            while(check <= e){
                temp = check
                while(temp <= e){
                    countList[temp]++
                    temp += check
                }
                check++
            }
            //println(countList)
            starts.forEach{
                val maxValue =  countList.subList(it,countList.size).maxOrNull()!!
                for(i in it .. countList.size-1){
                    if(countList[i] == maxValue){
                        answer += i
                        break
                    }
                }
            }
            return answer
        }
    }


    상기코드를 통해 실패한 후 혼자 노트에 적으면서 빨리 구할 수 있는 방법을 고민하다 보니 수별로 나오는 횟수는 해당 수의 약수의 갯수와 동일하다는 점을 확인하여 이를 토대로 코드를 작성 하였었으나 실패했었습니다.
    원인은 작성하고 알아보니 제가 작성한 코드에서 제곱근을 이용한 약수의 갯수 구하기도 시간초과가 된다는 점이였습니다. 그래서 약수의 개수를 구하는 함수등을 찾아보고 작성해본 다음 시간초과가 나지 않는 방법을 찾아 적용 후
    starts의 값과 동일한 인덱스에 해당 값이 나왔을때 최빈값을 log(n)에 찾을 수 있는 maxList를 작성 후 내림차순으로 작성하였으며, starts의 값을 확인하며 answer에 저장할 수 있도록 작성하였습니다.
    (개인적으로 영우는 천재인듯 싶었습니다.......ㅋㅋㅋㅋ 진짜 9~10번 시간 초과를 코드를 작성하면서 몇번을 봤는지 모르겠습니다ㅠㅜ 코드를 모두 작성할때는 어려워 보이던게 작성 후에는 왜이렇게 간단해 보이는지 모르겠습니다. 저만 이런 건 아니겠죠...?)
    최초 통과한 코드는 하기 코드가 아니지만 너무 지저분하게 작성한 것 같아 한번 정리 및 수정 하였습니다.

    class Solution {
        fun solution(e: Int, starts: IntArray): IntArray {
            var answer = IntArray(starts.size)
            var countList = MutableList(e + 1) { 0 }
            var maxList = IntArray(e + 1) { it }
    
            for (i in 1 .. e) {
                for (j in 1 .. (e/i) ) {
                    countList[i*j]++
                }
            }
    
            var maxValue = countList.last()
            var tempIndex = countList.size
    
            for(i in (countList.size-1) downTo 0){
               if(countList[i] < maxValue ){
                   maxList[i] = tempIndex
               } else {
                   maxValue = countList[i]
                   tempIndex = i
                   maxList[i] = tempIndex
               }
            }
    
            // println(countList)
            // println(maxList)
    
            for (i in starts.indices) {
                answer[i] = maxList[starts[i]]
            }
    
            return answer
        }
    }

    하기는 상기 코드의 실행 결과 입니다.

    테스트 1 통과 (5.69ms, 63.2MB)
    테스트 2 통과 (7.47ms, 61.3MB)
    테스트 3 통과 (6.14ms, 61.4MB)
    테스트 4 통과 (6.34ms, 60.7MB)
    테스트 5 통과 (7.98ms, 60MB)
    테스트 6 통과 (10.16ms, 61.2MB)
    테스트 7 통과 (25.13ms, 61.2MB)
    테스트 8 통과 (37.76ms, 62.8MB)
    테스트 9 통과 (249.74ms, 88.9MB)
    테스트 10 통과 (3223.99ms, 125MB

Designed by Tistory.