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

Kakao 2022 Blind Test - Lv3. μ–‘κ³Ό λŠ‘λŒ€ (Java)

by Edlin 2022. 6. 25.

문제 μš”μ•½

2μ§„ 트리 λͺ¨μ–‘인 μ΄ˆμ›μ˜ 각 λ…Έλ“œμ— μ–‘κ³Ό λŠ‘λŒ€κ°€ ν•œ λ§ˆλ¦¬μ”© λ†“μ—¬μžˆλ‹€. λ£¨νŠΈλ…Έλ“œμ—μ„œ μΆœλ°œν•˜μ—¬ 각 λ…Έλ“œλ₯Ό λŒμ•„λ‹€λ‹ˆλ©° 양을 λͺ¨μ„ λ•Œ, μ΅œλŒ€λ‘œ λͺ¨μ„ 수 μžˆλŠ” μ–‘μ˜ κ°œμˆ˜λŠ”?

 

[문제 μ„€λͺ…] 

  • 2μ§„ 트리의 각 λ…Έλ“œλ₯Ό λ°©λ¬Έν•˜μ—¬ μ–‘κ³Ό λŠ‘λŒ€λ₯Ό λͺ¨μ€λ‹€.
  • λͺ¨μ•„μ§„ λŠ‘λŒ€μ˜ κ°œμˆ˜κ°€ μ–‘μ˜ κ°œμˆ˜λ³΄λ‹€ λ§Žκ±°λ‚˜ 같을 λ•Œ, λŠ‘λŒ€λŠ” 양을 λͺ¨λ‘ μž‘μ•„ λ¨ΉλŠ”λ‹€.
  • 각각 μ—°κ²°λœ λ…Έλ“œλ“€μ„ λ‹€μ–‘ν•œ μˆœμ„œλ‘œ λ°©λ¬Έν•˜μ—¬ μ΅œλŒ€λ‘œ λͺ¨μ„ 수 μžˆλŠ” μ–‘μ˜ 개수λ₯Ό κ΅¬ν•˜λΌ. 

 

[μ œν•œ 사항]

  1. info: λ…Έλ“œμ˜ 정보 (0: μ–‘, 1: λŠ‘λŒ€) (2 ≤ info의 길이 ≤ 17) / info[0]은 항상 0이닀.
  2. edges: μ„œλ‘œ μ—°κ²°λœ λ…Έλ“œ 정보 (μ„Έλ‘œ ν–‰μ˜ 길이 = info의 길이 - 1, κ°€λ‘œ ν–‰μ˜ 길이 = 2) 
info edges result
[0,0,1,1,1,0,1,0,1,0,1,1] [[0,1],[1,2],[1,4],[0,8],[8,7],[9,10],[9,11],
[4,3],[6,5],[4,6],[8,9]]
5

 


문제 μ ‘κ·Ό 

  • κΉŠμ΄μš°μ„ νƒμƒ‰(dfs)을 μ‚¬μš©
  • λ°©λ¬Έ μˆœμ„œμ— 따라 λŠ‘λŒ€κ°€ 양을 μž‘μ•„ 먹을 μˆ˜λ„, μž‘μ•„λ¨Ήμ§€ μ•Šμ„ μˆ˜λ„ 있기 λ•Œλ¬Έμ— λͺ¨λ“  경우의 수λ₯Ό 탐색
  • λ‹€λ§Œ, ν˜„ λ…Έλ“œ μ‹œμ μ—μ„œ μžμ‹ μ„ 포함해 λŠ‘λŒ€μ™€ μ–‘μ˜ 수λ₯Ό κ³„μ‚°ν–ˆμ„ λ•Œ, λŠ‘λŒ€ μˆ˜κ°€ 양보닀 λ§Žμ„ λ•ŒλŠ” 더이상 트리λ₯Ό νƒμƒ‰ν•˜μ§€ μ•ŠλŠ”λ‹€. 
    • 양이 λŠ‘λŒ€λ₯Ό μž‘μ•„λ¨Ήμ–΄ μ–‘μ˜ μˆ˜κ°€ μ΅œλŒ€μž„μ„ 보μž₯ν•˜μ§€ λͺ»ν•œλ‹€.
μžμ„Έν•œ μ ‘κ·Ό 법은 μ½”λ“œμ˜ 주석을 ν™•μΈν•˜μ„Έμš” πŸ™‚
import java.util.*;

public class Solution {

    public static void main(String[] args) {
        int result = solution(new int[]{0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0},
                new int[][]{{0, 1}, {0, 2}, {1, 3}, {1, 4}, {2, 5}, {2, 6}, {3, 7}, {4, 8}, {6, 9}, {9, 10}});
        System.out.println(result);
    }

    static ArrayList<Integer>[] tree;
    static int max = Integer.MIN_VALUE;

    public static int solution(int[] info, int[][] edges) {
        tree = new ArrayList[info.length];

        for (int[] edge : edges) {
            int parent = edge[0];
            int child = edge[1];
            if (tree[parent] == null) {
                tree[parent] = new ArrayList<>();
            }
            tree[parent].add(child);
        }

        // visit λΌλŠ” boolean λ°°μ—΄λ‘œ 방문을 μ²˜λ¦¬ν•˜μ§€ μ•Šκ³  λ°©λ¬Έν•  λ…Έλ“œλ₯Ό λ‹΄κ³  μžˆλŠ” 리슀트λ₯Ό λ§Œλ“ λ‹€
        List<Integer> visit_list = new ArrayList<>();
        // 본격적으둜 탐색을 μ‹œμž‘ν•˜κΈ° μ „, ν˜„μž¬ λ…Έλ“œ 0 (루트)λ₯Ό λ°©λ¬Έν•  λ…Έλ“œμ— μΆ”κ°€ν•œλ‹€.
        visit_list.add(0);
        // 탐색을 μ‹œμž‘ν•œλ‹€.
        dfs(0, 0, 0, visit_list, info);
        return max;
    }

    private static void dfs(int current, int sheep, int wolf, List<Integer> visit_list, int[] info) {

        // λ°©λ¬Έν•  λ…Έλ“œκ°€ 양이라면 μ–‘μ˜ 수λ₯Ό 1 μ¦κ°€μ‹œν‚¨λ‹€.
        // λ°˜λŒ€μ˜ 경우 λŠ‘λŒ€μ˜ 수λ₯Ό 1 μ¦κ°€μ‹œν‚¨λ‹€.
        if (info[current] == 0) sheep++;
        else wolf++;


        // λ§Œμ•½ ν˜„μž¬ λ…Έλ“œ μ‹œμ μ—μ„œ λŠ‘λŒ€μ˜ μˆ˜κ°€ μ–‘μ˜ μˆ˜λ³΄λ‹€ λ§Žλ‹€λ©΄ 더이상 νƒμƒ‰ν•˜μ§€ μ•ŠλŠ”λ‹€.
        if (wolf >= sheep) return;

        // λ§Œμ•½ ν˜„μž¬ λ…Έλ“œ μ‹œμ μ—μ„œ μ–‘μ˜ μˆ˜κ°€ μ΅œλŒ€ μ–‘μ˜ μˆ˜λ³΄λ‹€ 많으면 값을 κ°±μ‹ ν•œλ‹€.
        max = Math.max(sheep, max);

        // visit_listλ₯Ό λ³΅μ‚¬ν•˜μ§€ μ•Šκ³  μ“Έ 경우, 같은 객체λ₯Ό κ°€λ¦¬μΌœ visit_list의 값이 훼손될 수 μžˆλ‹€.
        List<Integer> copied_list = new ArrayList<>();
        copied_list.addAll(visit_list);
        // μžμ‹λ…Έλ“œκ°€ μžˆλ‹€λ©΄ λ°©λ¬Έ λ¦¬μŠ€νŠΈμ— μΆ”κ°€μ‹œν‚¨λ‹€.
        if (tree[current] != null) {
            for (int each : tree[current])
                copied_list.add(each);
        }
        // ν˜„μž¬ νƒμƒ‰ν•˜λ €λŠ” λ…Έλ“œλŠ” λ°©λ¬Έ λ¦¬μŠ€νŠΈμ—μ„œ μ œκ±°ν•œλ‹€.
        copied_list.remove(Integer.valueOf(current));

        // μ°¨λ‘€λŒ€λ‘œ λ…Έλ“œλ“€μ„ λ°©λ¬Έν•œλ‹€.
        for (int next : copied_list) {
            dfs(next, sheep, wolf, copied_list, info);
        }
    }
}

λŠλ‚€μ 

처음 탐색할 λ•Œ, 쀑볡 방문을 쀄이기 μœ„ν•˜μ—¬ λ°©λ¬Έν•˜λŠ” λ…Έλ“œκΉŒμ§€ κ°€μ§ˆ 수 μžˆλŠ” μ΅œλŒ€ μ–‘μ˜ 개수λ₯Ό memoizationν•˜λŠ” 방법을 μƒκ°ν–ˆλ‹€.

κ·ΈλŸ¬λ‚˜ λ°©λ¬Έ μˆœμ„œμ— 따라 λ°©λ¬Έν•˜λŠ” λ…Έλ“œ μ‹œμ μ—μ„œ κ°€μ§ˆ 수 μžˆλŠ” μ–‘μ˜ μ΅œλŒ€ κ°œμˆ˜κ°€ 달라지기 λ•Œλ¬Έμ— memoization이 ν•„μš”ν•˜μ§€ μ•Šμ„ 것이라 결둜 λ‚΄λ Έλ‹€. μ΄λ•Œ λ¬Έμ œλŠ” λ§Žμ€ dfs둜 인해 μž¬κ·€μ˜ 쀑볡이 λ§Žμ•„μ§„λ‹€λŠ” 것인데, μ€‘λ³΅μ˜ 수λ₯Ό 쀄이기 μœ„ν•˜μ—¬ λŠ‘λŒ€μ™€ μ–‘μ˜ μˆ˜κ°€ κ°™λ‹€λ©΄ 더이상 탐색을 μ§„ν–‰ν•˜μ§€ μ•ŠλŠ” 쑰건을 μΆ”κ°€ν•˜μ˜€λ‹€. 

 

문제 링크: https://programmers.co.kr/learn/courses/30/lessons/92343
 

μ½”λ”©ν…ŒμŠ€νŠΈ μ—°μŠ΅ - μ–‘κ³Ό λŠ‘λŒ€

[0,0,1,1,1,0,1,0,1,0,1,1] [[0,1],[1,2],[1,4],[0,8],[8,7],[9,10],[9,11],[4,3],[6,5],[4,6],[8,9]] 5 [0,1,0,1,1,0,1,0,0,1,0] [[0,1],[0,2],[1,3],[1,4],[2,5],[2,6],[3,7],[4,8],[6,9],[9,10]] 5

programmers.co.kr

 

λŒ“κΈ€