ABOUT ME

개발 및 게임, 기타 등등

Today
Yesterday
Total
  • Programmers 순위 검색
    알고리즘 풀이/Search 2021. 8. 27. 23:19

    링크 : https://programmers.co.kr/learn/courses/30/lessons/72412

     

    코딩테스트 연습 - 순위 검색

    ["java backend junior pizza 150","python frontend senior chicken 210","python frontend senior chicken 150","cpp backend senior pizza 260","java backend junior chicken 80","python backend senior chicken 50"] ["java and backend and junior and pizza 100","pyt

    programmers.co.kr

    2021 KAKAO BLIND RECRUITMENT 순위 검색

     

    이거 풀때 너무 힘들어서,,, 작성한다

     

    첫번째로 접근한 방법은 input인 info List를 객체로 변환해 저장하고, 죄다 비교하는 거였다.

    당연히 효율성에서 빵점이 나왔다.

    Kakao Tech에서 나온 해설을 열심히 보며 코드를 작성했다.

     

    예시

        info 1 : "java backend junior pizza 150"

        info 2 : "java frontend senior pizza 200"

     

    1. info 정보 찢기

    만약 info1로 "java backend junior pizza 150" 이 들어왔다고 하면,

    질문으로 "- backend junior pizza" 가 들어오거나 "java - junior pizza"가 들어와도 모두 해당이 된다.

    그래서 "java backend junior pizza"로 query가 통과될 수 있는 모든 경우의 수를 만든다. (그게 16가지)

     

      언어 분야 경력 음식 점수
    1 java backend junior pizza 150
    2 - backend junior pizza 150
    3 java - junior pizza 150
    4 java backend - pizza 150
    5 java backend junior - 150
    6 - - junior pizza 150
    7 - backend - pizza 150
    8 - backend junior - 150
    9 java - - pizza 150
    10 java - junior - 150
    11 java backend - - 150
    12 - - - pizza 150
    13 - - junior - 150
    14 - backend - - 150
    15 java - - - 150
    16 - - - - 150

    이렇게 한명의 지원자 정보에 대해 16가지로 나타낼 수 있다.

    다음 지원자 정보인 "java frontend senior pizza 200"을 info2라고 한다면,

    info2 또한 위 표처럼 16가지로 쪼개질 수 있다. 그 중 info1과 겹치는 경우는

     

    언어 분야 경력 음식 점수
    java - - pizza [150, 200]
    - - - pizza [150, 200]
    java - - - [150, 200]
    - - - - [150, 200]

    이렇게 4가지가 될 것이다.

    만약 query로 "java - - pizza 170"이 들어온다면, 위의 표에서 점수에서 170이 넘는 지원자는 한명 뿐이니, 답은 1이 된다.

     

    이제 언어, 분야, 경력, 음식을 합쳐서 Map의 key값으로 만들고, 점수 List를 value로 설정한다.

    이렇게 하면 반을 왔다.

     

    이대로 모두 순차적으로 점수를 탐색하면 효율성에서 0점을 맞는다.

    Kakao Tech에선 이진 탐색(binary search)을 사용하기를 권한다.

    우선 map의 각 value들을 정렬한 뒤, binary search를 이용해 탐색하면 답을 구할 수 있는데

     

    Kotlin에서 제공하는 binarySearch 함수는 동일한 요소가 있는 경우 제일 최소 인덱스 반환을 보장하지 않는다고 하여

    직접 구현했다.

     

    fun recursive(map: MutableMap<String, MutableList<Int>>, strs: List<String>, checked: Array<Boolean>, index : Int, depth: Int, max_depth: Int) {
        if(depth == max_depth) {
            // check된곳 "-"로 치환
            var str = StringBuilder()
    
            (0 until 4).forEach { j ->
                if (checked[j]) {
                    str.append("-")
                } else {
                    str.append(strs[j])
                }
            }
    
            val key = str.toString()
            val score = strs[4].toInt()
            if(map.containsKey(key)) {
                map[key]!!.add(score)
            }else {
                map[key] = mutableListOf(score)
            }
        }
    
        for(i in index until 4) {
            checked[i] = true
            recursive(map, strs, checked, i+1,depth+1, max_depth)
            checked[i] = false
        }
    }
    
    fun binarySearch(list: MutableList<Int>, target: Int):Int {
        var start = 0
        var end = list.size
        var mid: Int
        while (end - start > 0) {
            mid = (start + end) / 2
            if(target <= list[mid]) {
                end = mid
            }
            else {
                start = mid + 1
            }
        }
    
        return end
    }
    
    class Solution {
        fun solution(info: Array<String>, query: Array<String>): IntArray {
            var answerList = mutableListOf<Int>()
            var info_map = mutableMapOf<String, MutableList<Int>>()
    
            for (i in info) {
                val splitInfo = i.split(" ")
    
                for(j in 0..4){
                    recursive(info_map, splitInfo, Array(4) {false}, 0,0, j)
                }
            }
    
            for(k in info_map.keys) {
                info_map[k]!!.sort()
            }
    
            for(q in query) {
                val str = q.replace("and ", "").split(" ")
                val key = str[0] + str[1] + str[2] + str[3]
    
                when(val scoreList = info_map[key]) {
                    null -> answerList.add(0)
                    else -> answerList.add(scoreList.size - binarySearch(scoreList, str[4].toInt()))
                }
            }
            return answerList.toIntArray()
        }
    }

     

    반응형

    댓글

Designed by Tistory.