樹
二叉樹的層次遍歷
給定一個二叉樹,返回其按層次遍歷的節點值。 (即逐層地,從左到右訪問所有節點)。
給定二叉樹: [3,9,20,null,null,15,7],返回其層次遍歷結果:[[3],[9,20],[15,7]]。
思路: 二叉樹有四種形態,單節點,只有左子樹,或者只有右子樹,或者左右子樹都存在,所以需要把每一層的節點數目記錄下來。數據結構選擇隊列,先進先出。
/**
* 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:
vector<vector<int>> levelOrder(TreeNode* root) {
queue<TreeNode*> Q;
vector<vector<int>> res;
int index = 0;
if(root){
Q.push(root);
index++;
}
while(!Q.empty()){
vector<int> Array;
int cnt = 0;
while(index--){
TreeNode* tmp = Q.front();
Q.pop();
Array.push_back(tmp->val);
if(tmp->left) {
Q.push(tmp->left);
cnt++;
}
if(tmp->right){
Q.push(tmp->right);
cnt++;
}
}
res.push_back(Array);
index = cnt;
}
return res;
}
};
二叉樹的中序遍歷
給定一個二叉樹,返回它的中序遍歷。
思路: 使用棧,先進後出
/**
* 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:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> Array;
stack<TreeNode*> s;
TreeNode* current=root;
while(current || !s.empty()){
while(current){
s.push(current);
current = current->left;
}
current = s.top();
s.pop();
Array.push_back(current->val);
current = current->right;
}
return Array;
}
};
驗證二叉搜索樹
給定一個二叉樹,判斷其是否是一個有效的二叉搜索樹。
假設一個二叉搜索樹具有如下特徵:
節點的左子樹只包含小於當前節點的數。
節點的右子樹只包含大於當前節點的數。
所有左子樹和右子樹自身必須也是二叉搜索樹。
思路: 二叉搜索樹的中序遍歷是一個遞增的數列
/**
* 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) {
stack<TreeNode*> S;
int tmp= INT_MIN;
int first = 0;
while(!S.empty() || root){
while(root){
S.push(root);
root = root->left;
}
root = S.top();
S.pop();
if(first&&root->val <= tmp){
return false;
}
first++;
tmp = root->val;
root = root->right;
}
return true;
}
};
從前序與中序遍歷序列構造二叉樹
根據一棵樹的前序遍歷與中序遍歷構造二叉樹。
注意:
你可以假設樹中沒有重複的元素。
思路: 前序遍歷的第一個元素一定是根節點,基於這個性質就可以把中序遍歷切分成兩部分,然後再對左半部分和右半部分進行上述迭代。
/**
* 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:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
int n = preorder.size();
int cnt = 0;
return build(preorder, inorder, cnt, 0, n-1);
}
TreeNode* build(vector<int>&preorder, vector<int>& inorder, int& cnt, int left, int right){
if(cnt==preorder.size()) return 0;
//
int index = 0;
for(int i=left;i<=right;i++){
if(inorder[i]==preorder[cnt]){
index = i;
break;
}
}
TreeNode* node = new TreeNode(preorder[cnt]);
if(left<index){
cnt++;
node->left = build(preorder, inorder, cnt, left, index-1);
}
if(index<right){
cnt++;
node->right = build(preorder, inorder, cnt, index+1, right);
}
return node;
}
};
二叉樹的最近公共祖先
給定一個二叉樹, 找到該樹中兩個指定節點的最近公共祖先。
百度百科中最近公共祖先的定義爲:“對於有根樹 T 的兩個結點 p、q,最近公共祖先表示爲一個結點 x,滿足 x 是 p、q 的祖先且 x 的深度儘可能大(一個節點也可以是它自己的祖先)。”
說明:
- 所有節點的值都是唯一的。
- p、q 爲不同節點且均存在於給定的二叉樹中。
思路: 當節點p和q同在子樹時,公共節點爲兩個節點中深度最淺的那個;當節點p和q在不同子樹時。公共節點爲根節點。
/**
* 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:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(root==NULL || root==p || root==q){
return root;
}
TreeNode* left = lowestCommonAncestor(root->left, p, q);
TreeNode* right = lowestCommonAncestor(root->right, p, q);
if(left && right) {
return root;
}
else if(left){
return left;
}
else if(right){
return right;
}
return NULL;
}
};
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/validate-binary-search-tree
著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。