leetcode - lowest common ancestor of a binary tree(java)

silver·2021년 7월 1일

level - medium

[문제 내용]
주어진 이진 트리에서 p와 q의 공통된 조상을 찾아 반환(자기자신도 조상에 포함)

[example 1]

Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
Output: 3
Explanation: The LCA of nodes 5 and 1 is 3.

[example 2]

Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
Output: 5
Explanation: The LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself according to the LCA definition.

[example 3]

Input: root = [1,2], p = 1, q = 2
Output: 1

[해결 방법]
재귀를 활용하여 왼쪽 오른쪽 탐색하며
해당하는 후손을 찾았을 경우 후손을 저장하고 true 를 반환해
해당 true를 반환받은 곳도 모두 저장한다.
그렇게 찾은 직계들을 비교하여 공통된 직계를 찾아 반환한다.

TreeNode 구조는 아래와 같다.

public class TreeNode {
     int val;
     TreeNode left;
     TreeNode right;
     TreeNode(int x) { val = x; }
 }

해결 코드는 아래와 같다.

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        ArrayList<TreeNode> pAncestor = new ArrayList<>();
        ArrayList<TreeNode> qAncestor = new ArrayList<>();
        findDescendant(root, p, pAncestor);	// p에 해당하는 직계 찾기
        findDescendant(root, q, qAncestor);	// q에 해당하는 직계 찾기

        // 공통 조상 찾기
        TreeNode common = null;
        for(int i=0; i<pAncestor.size(); i++) {
            TreeNode ancestor = pAncestor.get(i);
            for(int j=0; j<qAncestor.size(); j++) {
                if(ancestor == qAncestor.get(j)) {
                    common = ancestor;
                    break;	// 가장 낮은 조상을 반환해야 하므로 찾고 바로 빠져나온다
                }
            }
            if(common != null) break;
        }
        return common;
    }

    public boolean findDescendant(TreeNode root, TreeNode descendant, ArrayList<TreeNode> ancestor) {
        if(root == null) {
            return false;
        }

        if(root == descendant) {
            ancestor.add(descendant);
            return true;
        }

        // 왼쪽 직계 탐색
        if(findDescendant(root.left, descendant, ancestor)) {
            ancestor.add(root); // 해당하는 조상 모두 저장
            return true;
        }

        // 오른쪽 직계 탐색
        if(findDescendant(root.right, descendant, ancestor)) {
            ancestor.add(root);	// 해당하는 조상 모두 저장
            return true;
        }

        return false;
    }
}

0개의 댓글