[LeetCode] 687. Longest Univalue Path

Given a binary tree, find the length of the longest path where each node in the path has the same value. This path may or may not pass through the root.

Note: The length of path between two nodes is represented by the number of edges between them.

Example 1:

Input:

              5
             /             4   5
           / \             1   1   5

Output:

2

Example 2:

Input:

              1
             /             4   5
           / \             4   4   5

Output:

2

Note: The given binary tree has not more than 10000 nodes. The height of the tree is not more than 1000.

Similar with Binary Tree Max Path Sum,  for a given node t, the longest univalue path of this subtree whose root is t, the longest univalue path either includes t or not include t. If not including t, then the answer is either the longest univalue path of t‘s left subtree or right subtree. If including t, then the answer will be the sum between the left subtree longest straight path and the right subtree longest straight path.

Solution 1. Naive Recursion.

 1 class Solution {
 2     public int longestUnivaluePath(TreeNode root) {
 3         if(root == null) {
 4             return 0;
 5         }
 6         int leftLongestPath = longestUnivaluePath(root.left);
 7         int rightLongestPath = longestUnivaluePath(root.right);
 8         int longestPathWithoutCurrentNode = Math.max(leftLongestPath, rightLongestPath);
 9         int leftLongestSinglePath = longestSinglePath(root.left);
10         int rightLongestSinglePath = longestSinglePath(root.right);
11         int longestPathWithCurrentNode = 0;
12         if(root.left != null && root.left.val == root.val) {
13             longestPathWithCurrentNode += (leftLongestSinglePath + 1);
14         }
15         if(root.right != null && root.right.val == root.val) {
16             longestPathWithCurrentNode += (rightLongestSinglePath + 1);
17         }
18         return Math.max(longestPathWithoutCurrentNode, longestPathWithCurrentNode);
19     }
20     private int longestSinglePath(TreeNode node) {
21         if(node == null) {
22             return 0;
23         }
24         int leftLongestSinglePath = node.left != null && node.left.val == node.val ? longestSinglePath(node.left) + 1 : 0;
25         int rightLongestSinglePath = node.right != null && node.right.val == node.val ? longestSinglePath(node.right) + 1 : 0;
26         return Math.max(leftLongestSinglePath, rightLongestSinglePath);
27     }
28 }

The problem with solution is that when computing longest sing path for a subtree, it does not memoize any smaller subtrees‘ computation result. It always recursively exhaust all nodes of a subtree to get the longest single path. Since each longestSingePath call recursively calls another two longestSinglePath, the runtime for this method alone is O(2^h), where h is the height of a given subtree.

Solution 2. Recursion with memoization when computing longest single path for a subtree.

 1 class Solution {
 2     class ResultType {
 3         int singlePath;
 4         int maxPath;
 5         Integer val;
 6         ResultType(int sp, int mp, Integer v) {
 7             this.singlePath = sp;
 8             this.maxPath = mp;
 9             this.val = v;
10         }
11     }
12     public int longestUnivaluePath(TreeNode root) {
13         ResultType result = helper(root);
14         return result.maxPath;
15     }
16     private ResultType helper(TreeNode node) {
17         if(node == null) {
18             return new ResultType(0, 0, null);
19         }
20         ResultType left = helper(node.left);
21         ResultType right = helper(node.right);
22         int singlePath = 0;
23         if(left.val != null && left.val == node.val) {
24             singlePath = left.singlePath + 1;
25         }
26         if(right.val != null && right.val == node.val) {
27             singlePath = Math.max(singlePath, right.singlePath + 1);
28         }
29         int maxPathWithoutCurrentNode = Math.max(left.maxPath, right.maxPath);
30         int maxPathWithCurrentNode = 0;
31         if(left.val != null && left.val == node.val) {
32             maxPathWithCurrentNode += (left.singlePath + 1);
33         }
34         if(right.val != null && right.val == node.val) {
35             maxPathWithCurrentNode += (right.singlePath + 1);
36         }
37         int maxPath = Math.max(maxPathWithoutCurrentNode, maxPathWithCurrentNode);
38         return new ResultType(singlePath, maxPath, node.val);
39     }
40 }

Solution 3. A cleaner implementation with the same memoization idea

 1 class Solution {
 2     int ans = 0;
 3     public int longestUnivaluePath(TreeNode root) {
 4         helper(root);
 5         return ans;
 6     }
 7     private int helper(TreeNode node) {
 8         if(node == null) {
 9             return 0;
10         }
11         int leftMaxPath = helper(node.left);
12         int rightMaxPath = helper(node.right);
13         int leftMaxPathWithCurrentNode = node.left != null && node.left.val == node.val ? leftMaxPath + 1 : 0;
14         int rightMaxPathWithCurrentNode = node.right != null && node.right.val == node.val ? rightMaxPath + 1 : 0;
15         ans = Math.max(ans, leftMaxPathWithCurrentNode + rightMaxPathWithCurrentNode);
16         return Math.max(leftMaxPathWithCurrentNode, rightMaxPathWithCurrentNode);
17     }
18 }

原文地址:https://www.cnblogs.com/lz87/p/10222911.html

时间: 2024-10-13 04:10:48

[LeetCode] 687. Longest Univalue Path的相关文章

[LeetCode] 687. Longest Univalue Path 最长唯一值路径

Given a binary tree, find the length of the longest path where each node in the path has the same value. This path may or may not pass through the root. Note: The length of path between two nodes is represented by the number of edges between them. Ex

LeetCode 687. Longest Univalue Path 最长同值路径 (C++/Java)

题目: Given a binary tree, find the length of the longest path where each node in the path has the same value. This path may or may not pass through the root. The length of path between two nodes is represented by the number of edges between them. Exam

687. Longest Univalue Path

1 /** 2 * Definition for a binary tree node. 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 * }; 9 */ 10 11 static int wing=[]() 12 { 13 std::ios::sync_with_stdio

LeetCode | 1372. Longest ZigZag Path in a Binary Tree二叉树中的最长交错路径【Python】

LeetCode 1372. Longest ZigZag Path in a Binary Tree二叉树中的最长交错路径[Medium][Python][DFS] Problem LeetCode Given a binary tree root, a ZigZag path for a binary tree is defined as follow: Choose any node in the binary tree and a direction (right or left). I

[LeetCode][JavaScript]Longest Increasing Path in a Matrix

Longest Increasing Path in a Matrix Given an integer matrix, find the length of the longest increasing path. From each cell, you can either move to four directions: left, right, up or down. You may NOT move diagonally or move outside of the boundary

【Leetcode】Longest Increasing Path in a Matrix

题目链接:https://leetcode.com/problems/longest-increasing-path-in-a-matrix/ 题目: Given an integer matrix, find the length of the longest increasing path. From each cell, you can either move to four directions: left, right, up or down. You may NOT move dia

LeetCode #329. Longest Increasing Path in a Matrix

题目 Given an integer matrix, find the length of the longest increasing path. From each cell, you can either move to four directions: left, right, up or down. You may NOT move diagonally or move outside of the boundary (i.e. wrap-around is not allowed)

[leetcode]Memoization-329. Longest Increasing Path in a Matrix

en an integer matrix, find the length of the longest increasing path. From each cell, you can either move to four directions: left, right, up or down. You may NOT move diagonally or move outside of the boundary (i.e. wrap-around is not allowed). Exam

[leetcode]Longest Univalue Path

要注意边和节点数是不一样的 # Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = None class Solution: def longestUnivaluePath(self, root: TreeNode) -> int: result = [0] def backtrace(node,