zoukankan      html  css  js  c++  java
  • [LeetCode 1530] Number of Good Leaf Nodes Pairs

    Given the root of a binary tree and an integer distance. A pair of two different leaf nodes of a binary tree is said to be good if the length of the shortest path between them is less than or equal to distance.

    Return the number of good leaf node pairs in the tree.

     

    Example 1:

    Input: root = [1,2,3,null,4], distance = 3
    Output: 1
    Explanation: The leaf nodes of the tree are 3 and 4 and the length of the shortest path between them is 3. This is the only good pair.
    

    Example 2:

    Input: root = [1,2,3,4,5,6,7], distance = 3
    Output: 2
    Explanation: The good pairs are [4,5] and [6,7] with shortest path = 2. The pair [4,6] is not good because the length of ther shortest path between them is 4.
    

    Example 3:

    Input: root = [7,1,4,6,null,5,3,null,null,null,null,null,2], distance = 3
    Output: 1
    Explanation: The only good pair is [2,5].
    

    Example 4:

    Input: root = [100], distance = 1
    Output: 0
    

    Example 5:

    Input: root = [1,1,1], distance = 2
    Output: 1
    

     

    Constraints:

    • The number of nodes in the tree is in the range [1, 2^10].
    • Each node's value is between [1, 100].
    • 1 <= distance <= 10

    Solution that you came up during contest

    Since we have up to 1024 nodes, a O(N^2) solution is efficient to get accepted. The algorithm is very straightforward. 

    1.   Different tree nodes may share the same value, so for easier implemenation, do a dfs or bfs to relabel all N nodes from 0 to N - 1.

    2.  Convert the given binary tree to an undirected graph, either by dfs or bfs. Save all the leaf tree nodes during this conversion. 

    3.  For each leaf node, do a bfs on the converted graph, adding all other leaf nodes within specified distance. Terminate bfs if all nodes are exhausted or the current distance exceeds specified max distance.

    4.  Divide the total count from step 3 as we counted each pair twice.

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode() {}
     *     TreeNode(int val) { this.val = val; }
     *     TreeNode(int val, TreeNode left, TreeNode right) {
     *         this.val = val;
     *         this.left = left;
     *         this.right = right;
     *     }
     * }
     */
    class Solution {
        private int currLabel = 0;
        private boolean[] leafNodes;
        public int countPairs(TreeNode root, int distance) {
            dfsRelabel(root);
            leafNodes = new boolean[currLabel];
            List<Integer>[] g = buildGraph(root);
            int ans = 0;
            for(int i = 0; i < leafNodes.length; i++) {
                if(leafNodes[i]) {
                    ans += bfs(g, i, distance);
                }            
            }
            return ans / 2;
        }
        private int bfs(List<Integer>[] g, int node, int distance) {
            Queue<Integer> q = new LinkedList<>();
            boolean[] visited = new boolean[g.length];
            
            q.add(node);
            visited[node] = true;
            int d = 0, cnt = 0;
            
            while(q.size() > 0 && d <= distance) {
                int sz = q.size();
                for(int i = 0; i < sz; i++) {
                    int curr = q.poll();
                    if(curr != node && d <= distance && leafNodes[curr]) {
                        cnt++;
                    }
                    for(int u : g[curr]) {
                        if(!visited[u]) {
                            visited[u] = true;
                            q.add(u);
                        }
                    }
                }
                d++;
            }
            return cnt;
        }
        private void dfsRelabel(TreeNode node) {
            if(node != null) {
                dfsRelabel(node.left);
                dfsRelabel(node.right);
                node.val = currLabel;
                currLabel++;
            }
        }
        private void buildGraphHelper(List<Integer>[] g, TreeNode node) {
            if(node != null) {
                buildGraphHelper(g, node.left);
                buildGraphHelper(g, node.right);
                if(node.left != null) {
                    g[node.val].add(node.left.val);
                    g[node.left.val].add(node.val);
                }
                if(node.right != null) {
                    g[node.val].add(node.right.val);
                    g[node.right.val].add(node.val);
                }
                if(node.left == null && node.right == null) {
                    leafNodes[node.val] = true;
                }
            }
        }
        private List<Integer>[] buildGraph(TreeNode root) {
            List<Integer>[] g = new List[currLabel];
            for(int i = 0; i < g.length; i++) {
                g[i] = new ArrayList<>();
            }
            buildGraphHelper(g, root);
            return g;
        }
        
    }

    A better O(N) DFS solution

    For any good pair(u, v), there is only one subtree T such that u is in T's left-subtree and v is in T's right-subtree.(Or u in T's right-subtree, v in T's left-subtree). This means we can do a dfs on the entire tree and for each node(a different node represents the root of a different subtree), compute the following 2 results.

    1. LD[i]: where LD[i] is the number of leaf nodes that are of distance i to the left-subtree's root node;

    2.RD[i]: where RD[i] is the number of leaf nodes that are of distance i to the right-subtree's root node;

    Base case: 

    1. if node is null, return an array of 0.

    2. if node is a leafnode, set d[0] = 1, representing that there is 1 leaf node that is of distance 0 to the leaf node itself.

    General case:

    After getting LD and R, we enumerate all possible left and right leaf node distance combination and update final answer accordingly. We then update the current node's computing result using d[i + 1] = ld[i] + rd[i]; This means the number of leaf nodes that are of distance i + 1 to the current node is the sum of the leaf nodes of distance i from the left and right subtree. 

    Because we visit each node only once and distance is at most 10, the overall runtime is O(N).

    class Solution {
        private int ans = 0;
        public int countPairs(TreeNode root, int distance) {
            dfs(root, distance);
            return ans;
        }
        private int[] dfs(TreeNode node, int distance) {
            int[] d = new int[distance];
            if(node == null) {
                return d;
            }
            if(node.left == null && node.right == null) {
                d[0] = 1;
                return d;
            }
            int[] ld = dfs(node.left, distance);
            int[] rd = dfs(node.right, distance);
            for(int i = 0; i < ld.length; i++) {
                for(int j = 0; j < rd.length; j++) {
                    if(i + 1 + j + 1 <= distance) {
                        ans += ld[i] * rd[j];
                    }
                }
            }
            for(int i = 0; i < d.length - 1; i++) {
                d[i + 1] = ld[i] + rd[i];
            }
            return d;
        }
    }
  • 相关阅读:
    纽约顶级富婆鄙视链:4星|《我是个妈妈,我需要铂金包:一个耶鲁人类学博士的上东区育儿战争》
    2星|陈春花《顺德40年》:各种官宣的汇编,内容太虚,新信息太少
    人们喜欢传播符合自己三观的新闻,不在乎真假:4星|《环球科学》2018年12月号
    营销相关21本书
    5星|《辩论:美国制宪会议记录》:200年前的会议纪要
    3星|《品牌物理学》:理论没有实际应用案例,有推销软件的嫌疑
    关于思考的思考12本书,5星2本,4星7本
    Chrome插件 postman的使用方法详解!最全面的教程
    postman发送json请求,使用案例
    SUSE Enterprise Server 12 SP3 64 设置防火墙开放8080端口
  • 原文地址:https://www.cnblogs.com/lz87/p/13379941.html
Copyright © 2011-2022 走看看