λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
Algorithm/Coding Test

Kakao 2021 Blind Test - Lv2. μˆœμœ„κ²€μƒ‰ (Java)

by Edlin 2022. 5. 15.

문제 μš”μ•½

[쑰건]을 λ§Œμ‘±ν•˜λŠ” μ‚¬λžŒ 쀑 // μ½”λ”© ν…ŒμŠ€νŠΈ 점수λ₯Ό X점 이상 받은 μ‚¬λžŒμ€ λͺ¨λ‘ λͺ‡ λͺ…인가?

 

[쑰건]

  1. μ½”λ”© ν…ŒμŠ€νŠΈ μ°Έμ—¬ 개발 μ–Έμ–΄ ν•­λͺ© λ„· 쀑 ν•˜λ‚˜λ₯Ό μ„ νƒν•œλ‹€. (cpp, java, python, -)
  2. 지원 직ꡰ ν•­λͺ© μ…‹ 쀑 ν•˜λ‚˜λ₯Ό μ„ νƒν•œλ‹€. (backend, frontend, -)
  3. 지원 κ²½λ ₯ ꡬ뢄 ν•­λͺ© μ…‹ 쀑 ν•˜λ‚˜λ₯Ό μ„ νƒν•œλ‹€. (junior, senior, -)
  4. μ„ ν˜Έν•˜λŠ” μ†ŒμšΈ ν‘Έλ“œ μ…‹ 쀑 ν•˜λ‚˜λ₯Ό μ„ νƒν•œλ‹€.  (chicken, pizza, -)

- 쑰건 λͺ¨λ‘λ₯Ό 선택할 μˆ˜λ„ 있고 쑰건 쀑 μΌλΆ€λ§Œ 선택할 수 μžˆλ‹€.

- '-' λŠ” 아무 것도 μ„ νƒν•˜μ§€ μ•Šμ•˜λ‹€λŠ” 것을 μ˜λ―Έν•œλ‹€.


μ œμ•½ 쑰건

- info: μ§€μ›μ„œμ— μž…λ ₯ν•œ 4κ°€μ§€ 정보와 νšλ“ν•œ μ½”λ”© ν…ŒμŠ€νŠΈ 점수λ₯Ό ν•˜λ‚˜μ˜ λ¬Έμžμ—΄λ‘œ κ΅¬μ„±ν•œ λ°°μ—΄ (1 이상 50,000 μ΄ν•˜)

- query: κ°œλ°œνŒ€μ΄ κΆκΈˆν•΄ν•˜λŠ” 문의 쑰건 λ°°μ—΄ (ν˜•νƒœ: "[쑰건] X" - XλŠ” 점수 의미, 1이상 100,000 μ΄ν•˜) 

info query result
["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","python and frontend and senior and chicken 200","cpp and - and senior and pizza 250","- and backend and senior and - 150","- and - and - and chicken 100","- and - and - and - 150"] [1,1,1,1,2,4]

문제 μ ‘κ·Ό 

1. μ •ν™•μ„±λ§Œ 맞좘 예 (μ •λ ¬ / Binary Search 이용)

  • νš¨μœ¨μ„± ν…ŒμŠ€νŠΈλ₯Ό ν†΅κ³Όν•˜μ§€ λͺ»ν•œ 이유
    • μ΅œμ•…μ˜ 경우 query 개수 (100,000)
    • μ΅œμ•…μ˜ 경우 쑰건을 λ§Œμ‘±ν•˜λŠ” μ§€μ›μž 수 (50,000)
    • μ§€μ›μžμ˜ λͺ¨λ“  쑰건 탐색 (4)
    • O(100,000 * 50,000 * 4) = O(2e10)
    • 1 μ–΅ 번 계산을 1 초라 κ°€μ •ν•œλ‹€λ©΄, 1초 보닀 훨씬 였랜 μ‹œκ°„μ΄ κ±Έλ¦¬λ―€λ‘œ νš¨μœ¨μ„± ν…ŒμŠ€νŠΈ 톡과 X

 

// 22.05.15. - 2021 Kakao Blind - Lv2. μˆœμœ„ 검색

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;

public class Kakao_2021B_lv2 {
    public static void main(String[] args) {

        String[] info = new String[]{"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"};
        String[] query = new String[]{"java and backend and junior and pizza 100",
                "python and frontend and senior and chicken 200",
                "cpp and - and senior and pizza 250",
                "- and backend and senior and - 150",
                "- and - and - and chicken 100",
                "- and - and - and - 150"};
        int[] answer = solution(info, query);
        System.out.println(Arrays.toString(answer));
    }

    public static int[] solution(String[] info, String[] query) {

        int[] answer = new int[query.length];
        // input λΆ„λ₯˜
        ArrayList<String[]> infos = new ArrayList<>();
        for (int i = 0, size = info.length; i < size; i++) {
            String[] input = info[i].split(" ");
            infos.add(input);
        }

        // μ μˆ˜μ— 따라 μ˜€λ¦„μ°¨μˆœ μ •λ ¬
        Collections.sort(infos, new Comparator<String[]>() {
            @Override
            public int compare(String[] o1, String[] o2) {
                int item1 = Integer.parseInt(o1[4]);
                int item2 = Integer.parseInt(o2[4]);
                return item1 - item2;
            }
        });

        // 점수 λ°°μ—΄ λ§Œλ“€κΈ°
        int[] scores = new int[info.length];
        for (int i = 0, size = info.length; i < size; i++) {
            scores[i] = Integer.parseInt(infos.get(i)[4]);
        }

        ArrayList<Integer> result = new ArrayList<Integer>();
        for (int q = 0, size = query.length; q < size; q++) {
            String[] order = query[q].replace(" and ", " ").split(" ");
            int score = Integer.parseInt(order[order.length - 1]);
            int cnt = 0;

            // 점수λ₯Ό κΈ°μ€€μœΌλ‘œ μ‹œμž‘μ  μ°ΎκΈ°
            int start_point = search(scores, score);

            // queryλ₯Ό λΆ„μ„ν•˜μ—¬ 쑰건을 λ§Œμ‘±ν•˜λŠ” μ§€μ›μžκ°€ λͺ‡ λͺ… μžˆλŠ”μ§€ μ°ΎκΈ°
            for (int i = start_point, size_infos = infos.size(); i < size_infos; i++) {
                String[] each_info = infos.get(i);
                boolean flag = true;
                for (int j = 0; j < 4; j++) {
                    if (order[j].equals("-") || order[j].trim().equals(each_info[j]))
                        continue;
                    else {
                        flag = false;
                        break;
                    }
                }

                if (flag)
                    cnt++;
            }
            answer[q] = cnt;
        }
        return answer;
    }

    // binary search λ₯Ό μ΄μš©ν•œ μ‹œμž‘μ  μ°ΎκΈ°
    public static int search(int[] scores, int criteria) {

        int left = 0, right = scores.length;

        while (left < right) {
            int mid = (left + right) / 2;
            if (criteria > scores[mid]) {
                left = mid + 1;
            } else {
                right = mid;
            }
        }
        return left;
    }
}

 

2. μ •ν™•μ„± & νš¨μœ¨μ„± 톡과 (HashMap/ DFS/ Binary Search 이용)

  • μ–΄λ–»κ²Œν•˜λ©΄ 검색 수λ₯Ό 쀄일 수 μžˆμ„κΉŒ? HashMap 이용 
    • key: 쑰건의 μ‘°ν•© (점수 μ œμ™Έ) = 4 * 3 * 3 * 3 = 108
    • value: 점수
    • query의 μˆ˜κ°€ 쑰합을 λ§Œλ“œλŠ” 경우의 μˆ˜λ³΄λ‹€ 훨씬 크기 λ•Œλ¬Έμ— μ΅œμ•…μ˜ 경우 μ‹œκ°„ λ³΅μž‘λ„: O(100,000)

// 22.05.15. - 2021 Kakao Blind - Lv2. μˆœμœ„ 검색

import java.util.*;

public class Kakao_2021B_lv2 {
    public static void main(String[] args) {

        String[] info = new String[]{"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"};
        String[] query = new String[]{"java and backend and junior and pizza 100",
                "python and frontend and senior and chicken 200",
                "cpp and - and senior and pizza 250",
                "- and backend and senior and - 150",
                "- and - and - and chicken 100",
                "- and - and - and - 150"};
        int[] answer = solution(info, query);
        System.out.println(Arrays.toString(answer));
    }

    private static int[] solution(String[] info, String[] query) {
        int[] answer = new int[query.length];

        // info 기반 ν‚€ 생성
        HashMap<String, ArrayList<Integer>> hm = new HashMap<String, ArrayList<Integer>>();
        for (int i = 0, size = info.length; i < size; i++) {
            dfs(0, "", info[i].split(" "), hm);
        }

        // 각 key별 value μ˜€λ¦„μ°¨μˆœ μ •λ ¬
        for (String key : hm.keySet()) {
            Collections.sort(hm.get(key));
        }

        // 쑰건을 λ§Œμ‘±ν•˜λŠ” μ§€μ›μžκ°€ λͺ‡ λͺ…인지 μ°ΎκΈ°
        for (int i = 0, size = query.length; i < size; i++) {
            String[] each = query[i].replace(" and ", " ").split(" ");
            int criteria = Integer.parseInt(each[4]);

            StringBuilder key = new StringBuilder();
            for (int j = 0; j < 4; j++) {
                key.append(each[j].trim());
            }
            
            // λŸ°νƒ€μž„ μ—λŸ¬κ°€ λ°œμƒν–ˆλ˜ 이유: 
            // info 기반으둜 hashmap의 keyκ°€ λ§Œλ“€μ–΄μ§€κΈ° λ•Œλ¬Έμ—,
            // queryμ—μ„œ 찾고자 ν•˜λŠ” 쑰건이 hashmap의 key둜 μ‘΄μž¬ν•˜μ§€ μ•Šμ„ 수 μžˆμŠ΅λ‹ˆλ‹€. 
            if(hm.containsKey(key)){
            	ArrayList<Integer> scores = hm.get(key.toString());
            	int search_point = search(scores, criteria);
            	answer[i] = hm.get(key.toString()).size() - search_point;
            }
        }
        return answer;
    }

    // μ§€μ›μž 정보 기반 κ°€λŠ₯ν•œ λͺ¨λ“  ν‚€ 생성
    private static void dfs(int d, String str, String[] info, HashMap<String, ArrayList<Integer>> hm) {
        if (d == 4) {
            if (!hm.containsKey(str)) {
                ArrayList<Integer> list = new ArrayList<>();
                list.add(Integer.parseInt(info[4]));
                hm.put(str, list);
            } else {
                hm.get(str).add(Integer.parseInt(info[4]));
            }
            return;
        }

        dfs(d + 1, str + info[d], info, hm);
        dfs(d + 1, str + "-", info, hm);
    }

    // binary search λ₯Ό μ΄μš©ν•œ μ‹œμž‘μ  μ°ΎκΈ°
    private static int search(ArrayList<Integer> scores, int criteria) {

        int left = 0, right = scores.size()-1;

        while (left < right) {
            int mid = (left + right) / 2;
            if (criteria > scores.get(mid)) {
                left = mid + 1;
            } else {
                right = mid;
            }
        }
        return left;
    }
}

문제 링크: 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

곡식 ν•΄μ„€: https://tech.kakao.com/2021/01/25/2021-kakao-recruitment-round-1/
 

2021 카카였 μ‹ μž…κ³΅μ±„ 1μ°¨ 온라인 μ½”λ”© ν…ŒμŠ€νŠΈ for Tech developers λ¬Έμ œν•΄μ„€

μ§€λ‚œ 2020λ…„ 9μ›” 12일 ν† μš”μΌ μ˜€ν›„ 2μ‹œλΆ€ν„° 7μ‹œκΉŒμ§€ 5μ‹œκ°„ λ™μ•ˆ 2021 카카였 μ‹ μž… 개발자 곡채 1μ°¨ μ½”λ”© ν…ŒμŠ€νŠΈκ°€ μ§„ν–‰λ˜μ—ˆμŠ΅λ‹ˆλ‹€. ν…ŒμŠ€νŠΈμ—λŠ” 총 7개의 λ¬Έμ œκ°€ μΆœμ œλ˜μ—ˆμœΌλ©°, 개발 μ–Έμ–΄λŠ” C++, Java, Jav

tech.kakao.com

 

 

 

λŒ“κΈ€