树
二叉树的层次遍历
给定一个二叉树,返回其按层次遍历的节点值。 (即逐层地,从左到右访问所有节点)。
给定二叉树: [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;
}
};