[LeetCode] 298. Binary Tree Longest Consecutive Sequence 二叉樹最長連續序列


 

Given a binary tree, find the length of the longest consecutive sequence path.

The path refers to any sequence of nodes from some starting node to any node in the tree along the parent-child connections. The longest consecutive path need to be from parent to child (cannot be the reverse).

Example 1:

Input:

   1
    \
     3
    / \
   2   4
        \
         5

Output: 3

Explanation: Longest consecutive sequence path is 3-4-5, so return 3.

Example 2:

Input:

   2
    \
     3
    / 
   2    
  / 
 1

Output: 2 

Explanation: Longest consecutive sequence path is 2-3, not 3-2-1, so return 2.

 

這道題讓我們求二叉樹的最長連續序列,關於二叉樹的題基本都需要遍歷樹,而遞歸遍歷寫起來特別簡單,下面這種解法是用到了遞歸版的先序遍歷,對於每個遍歷到的節點,看節點值是否比參數值(父節點值)大1,如果是則長度加1,否則長度重置為1,然后更新結果 res,再遞歸調用左右子節點即可,參見代碼如下: 

 

解法一:

class Solution {
public:
    int longestConsecutive(TreeNode* root) {
        if (!root) return 0;
        int res = 0;
        dfs(root, root->val, 0, res);
        return res;
    }
    void dfs(TreeNode *root, int v, int out, int &res) {
        if (!root) return;
        if (root->val == v + 1) ++out;
        else out = 1;
        res = max(res, out);
        dfs(root->left, root->val, out, res);
        dfs(root->right, root->val, out, res);
    }
};

 

下面這種寫法是利用分治法的思想,對左右子節點分別處理,如果左子節點存在且節點值比其父節點值大1,則遞歸調用函數,如果節點值不是剛好大1,則遞歸調用重置了長度的函數,對於右子節點的處理情況和左子節點相同,參見代碼如下:

 

解法二:

class Solution {
public:
    int longestConsecutive(TreeNode* root) {
        if (!root) return 0;
        int res = 0;
        dfs(root, 1, res);
        return res;
    }
    void dfs(TreeNode *root, int len, int &res) {
        res = max(res, len);
        if (root->left) {
            if (root->left->val == root->val + 1) dfs(root->left, len + 1, res);
            else dfs(root->left, 1, res);
        }
        if (root->right) {
            if (root->right->val == root->val + 1) dfs(root->right, len + 1, res);
            else dfs(root->right, 1, res);
        }
    }
};

 

下面這種遞歸寫法相當簡潔,但是核心思想和上面兩種方法並沒有太大的區別,參見代碼如下:

 

解法三:

class Solution {
public:
    int longestConsecutive(TreeNode* root) {
        return helper(root, NULL, 0);
    }
    int helper(TreeNode *root, TreeNode *p, int res) {
        if (!root) return res;
        res = (p && root->val == p->val + 1) ? res + 1 : 1;
        return max(res, max(helper(root->left, root, res), helper(root->right, root, res)));
    }
};

 

上面三種都是遞歸的寫法,下面來看看迭代的方法,寫法稍稍復雜一些,用的還是 DFS 的思想,以層序來遍歷樹,對於遍歷到的節點,看其左右子節點有沒有滿足題意的,如果左子節點比其父節點大1,若右子節點存在,則排入 queue,指針移到左子節點,反之若右子節點比其父節點大1,若左子節點存在,則排入 queue,指針移到右子節點,依次類推直到 queue 為空,參見代碼如下:

 

解法四:

class Solution {
public:
    int longestConsecutive(TreeNode* root) {
        if (!root) return 0;
        int res = 0;
        queue<TreeNode*> q;
        q.push(root);
        while (!q.empty()) {
            int len = 1;
            TreeNode *t = q.front(); q.pop();
            while ((t->left && t->left->val == t->val + 1) || (t->right && t->right->val == t->val + 1)) {
                if (t->left && t->left->val == t->val + 1) {
                    if (t->right) q.push(t->right);
                    t = t->left;
                } else if (t->right && t->right->val == t->val + 1) {
                    if (t->left) q.push(t->left);
                    t = t->right;
                }
                ++len;
            }
            if (t->left) q.push(t->left);
            if (t->right) q.push(t->right);
            res = max(res, len);
        }
        return res;
    }
};

 

Github 同步地址:

https://github.com/grandyang/leetcode/issues/298

 

類似題目:

Longest Increasing Subsequence

 

參考資料:

https://leetcode.com/problems/binary-tree-longest-consecutive-sequence/

https://leetcode.com/problems/binary-tree-longest-consecutive-sequence/discuss/74548/C%2B%2B-solution-in-4-lines

https://leetcode.com/problems/binary-tree-longest-consecutive-sequence/discuss/74467/Simple-Recursive-DFS-without-global-variable

https://leetcode.com/problems/binary-tree-longest-consecutive-sequence/discuss/74468/Easy-Java-DFS-is-there-better-time-complexity-solution

 

LeetCode All in One 題目講解匯總(持續更新中...)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM