---
# System prepended metadata

title: 687. Longest Univalue Path
tags: [dfs, tree, Leetcode, medium, python, c++]

---

###### tags: `Leetcode` `medium` `tree` `dfs` `python` `c++`

# 687. Longest Univalue Path

## [題目連結:] https://leetcode.com/problems/longest-univalue-path/

## 題目:
Given the ```root``` of a binary tree, return 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 the path** between two nodes is represented by the number of edges between them.

![](https://i.imgur.com/1HyCyu0.png)
![](https://i.imgur.com/bQJ7voX.png)

## 解題想法:
* 此題為求最長的相同值路徑長度
    * 不需一定要經由root算起
* 對於求樹相關的路徑問題: 往**遞迴思考**
    * 需額外寫函式:
        * def getPath(self,root): 
            * 求當前root所構成的最長相同路徑長度
            * 為向下延伸的找長度，不能轉彎
    * **Step1**: 對當前root左右節點分別遞迴求其最長相同路徑長度
        * left=self.getPath(root.left)
        * right=self.getPath(root.right)
    * **Step2**: 判斷當前節點與左右子節點之關係
        * 初始:
            * lenOfLeft=0
            * lenOfRight=0
        * 若左子存在且root.val==root.left.val:
            * lenOfLeft=left+1
        * 若右子存在且root.val==root.right.val:
            * lenOfRight=right+1
    * **Step3**: 更新最終值與函式回傳值(**超重要易搞混**)
        * 更新最終的res:
            * **以當前root為中心可以彎曲+左+右**
            * res=max(res, lenOfLeft+lenOfRight)
        * 最終該getPath回傳值:
            * 回傳是以該root為起點的長度，是要向下延伸
            * 所以只能選左or右長的回傳
            * return max(lenOfLeft, lenOfRight)

    * 舉例case:
    ``` 
    此狀況 最長為2!!! 
             5
        5        6
    5       5   2   7
    ```
    
## Python:
``` python=
class TreeNode(object):
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
    def insertLeft(self,node):
        if self.left==None:
            self.left=TreeNode(node)
        else:
            self.left.insertLeft(node)
    def insertRight(self,node):
        if self.right==None:
            self.right=TreeNode(node)
        else:
            self.right.insertRight(node)
    def printTree(self):
        root=self
        stack=[root]
        res=[]
        while stack:
            root=stack.pop(0)
            res.append(root.val)
            if root.left:
                stack.append(root.left)
            if root.right:
                stack.append(root.right)
        print(res)
        
class Solution(object):
    def longestUnivaluePath(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        if not root:
            return 0
        self.res=0
        self.getPath(root)
        return self.res
    def getPath(self,root): #為向下延伸的 不能轉彎
        if not root:
            return 0
        left=self.getPath(root.left)
        right=self.getPath(root.right)
        lenOfLeft=0
        lenOfRight=0
        if root.left and root.left.val==root.val:
            lenOfLeft=left+1
        if root.right and root.right.val==root.val:
            lenOfRight=right+1
        #更新最大值  以該root為中心可以彎曲左+右
        self.res=max(self.res,lenOfLeft+lenOfRight)
        #但回傳以該root的長度 是要向下延伸 所以只能選左右長的回傳
        return max(lenOfLeft,lenOfRight)

root=TreeNode(5)
root.insertLeft(5)
root.insertRight(6)
root.left.insertLeft(5)
root.left.insertRight(5)
root.right.insertLeft(2)
root.right.insertRight(7)
root.printTree()

result=Solution()
ans=result.longestUnivaluePath(root)
print(ans) #2
```

## C++:
``` cpp=
#include<bits/stdc++.h>
using namespace std;
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    int longestUnivaluePath(TreeNode* root) {
        getPath(root);
        return res;
    }
    int getPath(TreeNode* root){
        if (!root)
            return 0;
        int left=getPath(root->left);
        int right=getPath(root->right);
        int lenOfLeft=0, lenOfRight=0;
        if (root->left && root->left->val==root->val)
            lenOfLeft=left+1;
        if (root->right && root->right->val==root->val)
            lenOfRight=right+1;
        res=max(res, lenOfLeft+lenOfRight);
        return max(lenOfLeft, lenOfRight);
    }

private:
    int res=0;
};
```