LeetCode刷題(二十二)-----樹-------medium部分(Java、C++)

102. 二叉樹的層次遍歷

給定一個二叉樹,返回其按層次遍歷的節點值。(即逐層地,從左到右訪問所有節點)。
例如:給定二叉樹:[3,9,20,null,null,15,7],

在這裏插入圖片描述
返回其層次遍歷結果:
[
[3],
[9,20],
[15,7]
]

思路一:
如何遍歷一棵樹

有兩種通用的遍歷樹的策略:
深度優先搜索(DFS)

在這個策略中,我們採用深度作爲優先級,以便從根開始一直到達某個確定的葉子,然後再返回根到達另一個分支。

深度優先搜索策略又可以根據根節點、左孩子和右孩子的相對順序被細分爲先序遍歷,中序遍歷和後序遍歷。

寬度優先搜索(BFS)

我們按照高度順序一層一層的訪問整棵樹,高層次的節點將會比低層次的節點先被訪問到。

下圖中的頂點按照訪問的順序編號,按照1-2-3-4-5的順序來比較不同的策略。

作者:LeetCode
鏈接:https://leetcode-cn.com/problems/binary-tree-level-order-traversal/solution/er-cha-shu-de-ceng-ci-bian-li-by-leetcode/
來源:力扣(LeetCode)
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。

116. 填充每個節點的下一個右側節點指針

給定一個完美二叉樹,其所有葉子節點都在同一層,每個父節點都有兩個子節點。二叉樹定義如下:
struct Node {
  int val;
  Node *left;
  Node *right;
  Node *next;
}
填充它的每個 next 指針,讓這個指針指向其下一個右側節點。如果找不到下一個右側節點,則將 next 指針設置爲 NULL。

初始狀態下,所有 next 指針都被設置爲 NULL。
示例:

在這裏插入圖片描述

輸入:
{"$id":"1","left":
{"$id":"2","left":
{"$id":"3","left":null,"next":null,"right":null,"val":4},"next":null,"right":
{"$id":"4","left":null,"next":null,"right":null,"val":5},"val":2},"next":null,"right":
{"$id":"5","left":
{"$id":"6","left":null,"next":null,"right":null,"val":6},"next":null,"right":
{"$id":"7","left":null,"next":null,"right":null,"val":7},"val":3},"val":1}

輸出:
{"$id":"1","left":
{"$id":"2","left":
{"$id":"3","left":null,"next":
{"$id":"4","left":null,"next":
{"$id":"5","left":null,"next":
{"$id":"6","left":null,"next":null,"right":null,"val":7},"right":null,"val":6},"right":null,"val":5},"right":null,"val":4},"next":
{"$id":"7","left":
{"$ref":"5"},"next":null,"right":
{" $ref":"6"},"val":3},"right":
{"$ref":"4"},"val":2},"next":null,"right":
{"$ref":"7"},"val":1}

解釋:給定二叉樹如圖 A 所示,你的函數應該填充它的每個 next 指針,以指向其下一個右側節點,如圖 B 所示。

思路一:拉拉鍊解法
在這裏插入圖片描述
我的:

/*
// Definition for a Node.
class Node {
public:
    int val;
    Node* left;
    Node* right;
    Node* next;

    Node() : val(0), left(NULL), right(NULL), next(NULL) {}

    Node(int _val) : val(_val), left(NULL), right(NULL), next(NULL) {}

    Node(int _val, Node* _left, Node* _right, Node* _next)
        : val(_val), left(_left), right(_right), next(_next) {}
};
*/
class Solution {
public:
    Node* connect(Node* root) 
    {
        if(!root)
        {
            return NULL;
        }    
        Node* left = root -> left;
        Node* right = root -> right; 
        while(left)
        {
            left -> next = right;
            left = left -> right;
            right = right -> left;
        }
        connect(root -> left);
        connect(root -> right);
        return root;
    }
};

98. 驗證二叉搜索樹

給定一個二叉樹,判斷其是否是一個有效的二叉搜索樹。
假設一個二叉搜索樹具有如下特徵:
節點的左子樹只包含小於當前節點的數。
節點的右子樹只包含大於當前節點的數。
所有左子樹和右子樹自身必須也是二叉搜索樹。
示例 1:

在這裏插入圖片描述
示例2:
在這裏插入圖片描述
思路一:
直覺
乍一看,這是一個平凡的問題。只需要遍歷整棵樹,檢查 node.right.val > node.val 和node.left.val < node.val 對每個結點是否成立。
在這裏插入圖片描述
問題是,這種方法並不總是正確。不僅右子結點要大於該節點,整個右子樹的元素都應該大於該節點。例如:
在這裏插入圖片描述
這意味着我們需要在遍歷樹的同時保留結點的上界與下界,在比較時不僅比較子結點的值,也要與上下界比較。
方法一: 遞歸
上述思路可以用遞歸法實現。首先將結點的值與上界和下界(如果有)比較。然後,對左子樹和右子樹遞歸進行該過程。
在這裏插入圖片描述
複雜度分析
• 時間複雜度 : O(N)。每個結點訪問一次。
• 空間複雜度 : O(N)。我們跟進了整棵樹。
方法二: 迭代
通過使用棧,上面的遞歸法可以轉化爲迭代法。這裏使用深度優先搜索,比廣度優先搜索要快一些。
在這裏插入圖片描述
複雜度分析
• 時間複雜度 : O(N)。每個結點訪問一次。
• 空間複雜度 : O(N)。我們跟進了整棵樹。

作者:LeetCode
鏈接:https://leetcode-cn.com/problems/validate-binary-search-tree/solution/yan-zheng-er-cha-sou-suo-shu-by-leetcode/
來源:力扣(LeetCode)
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。

我的:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    bool isValidBST(TreeNode* root) {
        return helper(root,LONG_MIN,LONG_MAX);
    }
    bool helper(TreeNode* cur,long lt,long rt){
        if(cur==NULL) return true;
        if(cur->val<=lt||cur->val>=rt) return false;
        if(helper(cur->left,lt,cur->val)&&helper(cur->right,cur->val,rt)) return true;
        return false;
    }

};


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章