LCA(Lowest Common Ancestor) ์•Œ๊ณ ๋ฆฌ์ฆ˜

1. LCA(Lowest Common Ancestor) ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋ž€? 

๋‘ ๊ฐœ์˜ ๋…ธ๋“œ์˜ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ๊ณตํ†ต๋œ ๋ถ€๋ชจ๋ฅผ ์ฐพ๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๋งํ•œ๋‹ค.

 

 

2. ์–ด๋–ป๊ฒŒ ์ฐพ์„ ์ˆ˜ ์žˆ์„๊นŒ? 

์œ„์˜ ํŠธ๋ฆฌ์—์„œ 9์™€ 13์˜ ๊ณตํ†ต ๋ถ€๋ชจ๋Š” ๋‘˜์˜ ๋ฐ”๋กœ ์œ„์— ์žˆ๋Š” 2์ด๋‹ค. ๋ฌผ๋ก  9์™€ 13๊ณผ ๊ฐ™์ด ๊ฐ™์€ Level์— ์žˆ๋Š” ๋…ธ๋“œ์ธ ๊ฒฝ์šฐ์— ๋‘ ๋…ธ๋“œ์˜ Level์„ ๋™์‹œ์— ํ•˜๋‚˜์”ฉ ์ค„์—ฌ๊ฐ€๋ฉฐ ์ฐพ์„ ์ˆ˜ ์žˆ๊ฒ ์ง€๋งŒ ๋งŒ์•ฝ ์„œ๋กœ ๋‹ค๋ฅธ Level์— ์žˆ๋Š” ๊ฒฝ์šฐ ๋™์‹œ์— ๊ฑฐ์Šฌ๋Ÿฌ ์˜ฌ๋ผ๊ฐ„๋‹ค ํ•œ๋“ค ๊ณตํ†ต ๋ถ€๋ชจ๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†๋‹ค. ๋”ฐ๋ผ์„œ Level์ด ๋‹ค๋ฅธ ๊ฒฝ์šฐ์—๋Š” ํ•˜๋‚˜์˜ ๋…ธ๋“œ๋ฅผ ๊ฑฐ์Šฌ๋Ÿฌ ์˜ฌ๋ผ๊ฐ€๋„๋ก ํ•˜์—ฌ ๊ฐ™์€ Level๋กœ ๋งž์ถฐ์ค˜์•ผ๋งŒ ํ•œ๋‹ค.

์ •๋ฆฌํ•˜์ž๋ฉด, ๋” ๊นŠ์€ Level์— ์žˆ๋Š” ๋…ธ๋“œ์˜ Level์„ ์ค„์—ฌ ์–•์€ Level์— ์žˆ๋Š” ๋…ธ๋“œ์™€ ๋™์ผํ•˜๊ฒŒ ๋งž์ถฐ์ค˜์•ผ ํ•œ๋‹ค. 

 

2.1. Level๊ณผ ๋ถ€๋ชจ ๋…ธ๋“œ ๊ตฌํ•˜๊ธฐ

์šฐ์„  ์œ„์˜ ๋กœ์ง์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋‹น์—ฐํ•˜๊ฒŒ๋„ ๊ฐ ๋…ธ๋“œ์˜ Level๊ณผ ๋ถ€๋ชจ ๋…ธ๋“œ๋ฅผ ๊ตฌํ•ด์•ผ๋งŒ ํ•œ๋‹ค.  BFS๋ฅผ ํ™œ์šฉํ•˜๋ฉด ๋ชจ๋“  ๋…ธ๋“œ์˜ Level๊ณผ ๋ถ€๋ชจ ๋…ธ๋“œ๋ฅผ ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค.  

 

Level๊ณผ ๋ถ€๋ชจ ๋…ธ๋“œ ๊ตฌํ•˜๊ธฐ ๋ถ€๋ถ„์„ ์ฝ”๋“œ๋กœ ์ง์ ‘ ๊ตฌํ˜„ํ•ด๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

    private void initialized(int[] tree) {
        Queue<Integer> queue = new LinkedList<>();
        queue.add(1);
        levels[1] = 0;
        parents[1] = 0;
        while(!queue.isEmpty()) {
            int temp = queue.poll();
            int leftNode = temp*2;
            int rightNode = temp*2+1;
            if(leftNode < tree.length) {
                queue.add(leftNode);
                levels[leftNode] = levels[temp] + 1;
                parents[leftNode] = temp;
            }

            if(rightNode < tree.length) {
                queue.add(rightNode);
                levels[rightNode] = levels[temp] + 1;
                parents[rightNode] = temp;
            }
        }
    }

2.2. LCA ๋ฉ”์ธ ๋กœ์ง

์ด์ œ ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋“ค์„ ๋ชจ๋‘ ๊ตฌํ–ˆ์œผ๋‹ˆ, ๋ฉ”์ธ ๋กœ์ง ๊ตฌํ˜„๋งŒ ๋‚จ์•˜๋‹ค. 

์šฐ๋ฆฌ๋Š” ์œ„์—์„œ ํ™•์ธํ–ˆ๋‹ค์‹œํ”ผ ๊ฐ™์€ Level์— ์žˆ๋Š” ๋…ธ๋“œ๋“ค์˜ LCA๋ฅผ ๊ตฌํ•˜๋Š” ๊ฒƒ์ด ํ›จ์”ฌ ์‰ฝ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ€์žฅ ๋จผ์ € ๋‘˜ ์ค‘ ๊นŠ์€ Level์— ์œ„์น˜ํ•œ ๋…ธ๋“œ๋ฅผ ๊ณจ๋ผ ์–•์€ Level์˜ ๋…ธ๋“œ์™€ ๋™์ผํ•œ Level๋กœ ์˜ฎ๊ฒจ์ค˜์•ผ ํ•œ๋‹ค.  ์ฆ‰, Level์ด ๊ฐ™์•„์งˆ ๋•Œ ๊นŒ์ง€ ๊นŠ์€ Level์— ์œ„์น˜ํ•œ ๋…ธ๋“œ๋Š” ๋ถ€๋ชจ ๋…ธ๋“œ๋ฅผ ํ†ตํ•ด ์œ„๋กœ ๊ฑฐ์Šฌ๋Ÿฌ ์˜ฌ๋ผ๊ฐ€์•ผ ํ•œ๋‹ค.

 

 ์ฝ”๋“œ๋กœ ์ง์ ‘ ๊ตฌํ˜„ํ•ด๋ณด์ž. 

    private int lca(int a, int b) {
        int aDepth = levels[a];
        int bDepth = levels[b];

        while(aDepth > bDepth) {
            a = parents[a];
            aDepth--;
        }

        while(aDepth < bDepth) {
            b = parents[b];
            bDepth--;
        }

        while(a!=b) {
            a = parents[a];
            b = parents[b];
            aDepth--;
            bDepth--;
        }

        return a;
    }