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;
}
};