GuilinDev

Lc0742

05 August 2008

742. Closest Leaf in a Binary Tree

给定二叉树的根,其中每个节点都有一个唯一值和一个目标整数 k,返回树中离目标 k 最近的叶节点的值。

最接近叶子意味着在二叉树上经过的最少边数到达树的任何叶子。此外,如果节点没有子节点,则称为叶子节点。

建图然后DFS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class Solution {
    public int findClosestLeaf(TreeNode root, int k) {
        Map<Integer, List<Integer>> map = new HashMap<>();
        build(map, root); //build an undirected graph
        return map.isEmpty()? root.val : dfs(map, root.val, k, -1)[1];
    }
    //this method returns [min distance to leaf, leaf value]
    private int[] dfs(Map<Integer, List<Integer>> map, int root, int start, int parent){
        boolean isLeaf = map.get(start).size() == 1 && start != root;
        int[] min = isLeaf? new int[]{0, start} : new int[]{1001, -1};
        for (int next : map.get(start)){
            if (next == parent) continue; //can't go back to where you came from.
            int[] res = dfs(map, root, next, start);
            if (min[0] > res[0]) min = res;
        }

        min[0]++;
        return min;
    }

    private void build(Map<Integer, List<Integer>> map, TreeNode root){
        if (root.right != null){
            map.computeIfAbsent(root.val, o -> new ArrayList<>()).add(root.right.val);
            map.computeIfAbsent(root.right.val, o -> new ArrayList()).add(root.val);
            build(map, root.right);
        }
        if (root.left != null){
            map.computeIfAbsent(root.val, o -> new ArrayList<>()).add(root.left.val);
            map.computeIfAbsent(root.left.val, o -> new ArrayList()).add(root.val);
            build(map, root.left);
        }
    }
}

BFS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
class Solution {
    /*
    1) First, preform DFS on root in order to find the node whose val = k, at the meantime use HashMap to keep record of all back edges from child to parent;
    2) Then perform BFS on this node to find the closest leaf node.
    

    */
    public int findClosestLeaf(TreeNode root, int k) {
        Map<TreeNode, TreeNode> backMap = new HashMap<>();   // store all edges that trace node back to its parent
        Queue<TreeNode> queue = new LinkedList<>();          // the queue used in BFS
        Set<TreeNode> visited = new HashSet<>();             // store all visited nodes
        
        // DFS: search for node whoes val == k
        TreeNode kNode = DFS(root, k, backMap);
        queue.add(kNode);
        visited.add(kNode);
        
        // BFS: find the shortest path
        while(!queue.isEmpty()) {
            TreeNode curr = queue.poll();
            if(curr.left == null && curr.right == null) {
                return curr.val;
            }
            if(curr.left != null && visited.add(curr.left)) {
                queue.add(curr.left);
            }
            if(curr.right != null && visited.add(curr.right)) {
                queue.add(curr.right);
            }
            if(backMap.containsKey(curr) && visited.add(backMap.get(curr))) {  // go alone the back edge
                queue.add(backMap.get(curr));
            }
        }
        return -1; // never hit
    }
    
    private TreeNode DFS(TreeNode root, int k, Map<TreeNode, TreeNode> backMap) {
        if(root.val == k) {
            return root;
        }
        if(root.left != null) {
            backMap.put(root.left, root);        // add back edge
            TreeNode left = DFS(root.left, k, backMap);
            if(left != null) return left;
        }
        if(root.right != null) {
            backMap.put(root.right, root);       // add back edge
            TreeNode right = DFS(root.right, k, backMap);
            if(right != null) return right;
        }
        return null;
    }
}