二叉树的最大深度
给定一个二叉树,找出其最大深度。
二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
说明: 叶子节点是指没有子节点的节点。
示例:
给定二叉树 [3,9,20,null,null,15,7],
3
/
9 20
/
15 7
返回它的最大深度 3 。
/**
* 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:
int maxDepth(TreeNode* root) {
if(root==NULL)
return 0;
return 1+max(maxDepth(root->left),maxDepth(root->right));
}
};
验证二叉搜索树
给定一个二叉树,判断其是否是一个有效的二叉搜索树。
假设一个二叉搜索树具有如下特征:
节点的左子树只包含小于当前节点的数。
节点的右子树只包含大于当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。
示例 1:
输入:
2
/ \
1 3
输出: true
示例 2:
输入:
5
/ \
1 4
/ \
3 6
输出: false
解释: 输入为: [5,1,4,null,null,3,6]。
根节点的值为 5 ,但是其右子节点值为 4
c++代码
方法一:
class Solution {
public:
bool isValidBST(TreeNode *root) {
return isValidBST(root, LONG_MIN, LONG_MAX);
}
bool isValidBST(TreeNode *root, long mn, long mx) {
if (!root) return true;
if (root->val <= mn || root->val >= mx) return false;
return isValidBST(root->left, mn, root->val) && isValidBST(root->right, root->val, mx);
}
};
方法二:
进行中序遍历,得到的结果正好是一个有序的。直接判断就可以了。
一般的二叉搜索树是左<=根<右,而这道题设定为左<根<右,那么就可以用中序遍历来做。因为如果不去掉左=根这个条件的话,那么下边两个数用中序遍历无法区分:
20 20
/ \
20 20
它们的中序遍历结果都一样,但是左边的是BST,右边的不是BST。去掉等号的条件则相当于去掉了这种限制条件。
/**
* 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) {
if(!root)
return true;
vector<int> vals;
inorder(root,vals);
for(int i=1;i<vals.size();i++)
{
if(vals[i]<=vals[i-1])
return false;
}
return true;
}
//中序遍历
void inorder(TreeNode* root,vector<int> &vals)
{
if(!root)
return;
inorder(root->left,vals);
vals.push_back(root->val);
inorder(root->right,vals);
}
};
对称二叉树
给定一个二叉树,检查它是否是镜像对称的。
例如,二叉树 [1,2,2,3,4,4,3] 是对称的。
1
/ \
2 2
/ \ / \
3 4 4 3
但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的:
1
/ \
2 2
\ \
3 3
说明:
如果你可以运用递归和迭代两种方法解决这个问题,会很加分。
思路
两个节点A和B对称等价于:
这两个节点上存储的值相等
节点A的左子树节点和节点B的右子树上的节点是对称的
节点A的右子树节点和节点A的左子树上的节点是对称的
c++代码
递归
/**
* 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 isSymmetric(TreeNode* root) {
if(!root)
return true;
return is(root->left,root->right);
}
bool is(TreeNode* p1,TreeNode* p2)
{
if(p1==NULL && p2==NULL)
return true;
if((p1==NULL&&p2!=NULL) ||(p2==NULL&&p1!=NULL))
return false;
return (p1->val==p2->val)&&is(p1->left,p2->right)&&is(p1->right,p2->left);
}
};
迭代
用栈
/**
* 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 isSymmetric(TreeNode* root) {
if(!root)
return true;
return is(root->left,root->right);
}
bool is(TreeNode* p1,TreeNode* p2)
{
stack<TreeNode*> s;
s.push(p1);
s.push(p2);
while(!s.empty())
{
TreeNode *tmp1=s.top();
s.pop();
TreeNode *tmp2=s.top();
s.pop();
if(!tmp1&&!tmp2)
continue;
if(!tmp1||!tmp2||tmp1->val!=tmp2->val)
return false;
s.push(tmp1->left);
s.push(tmp2->right);
s.push(tmp1->right);
s.push(tmp2->left);
}
return true;
}
};
二叉树的层次遍历
给定一个二叉树,返回其按层次遍历的节点值。 (即逐层地,从左到右访问所有节点)。
例如:
给定二叉树: [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回其层次遍历结果:
[
[3],
[9,20],
[15,7]
]
c++代码
思路:
借助队列,每一层的节点都进入队列,遍历完出队。
/**
* 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) {
if(!root)
return {};
vector<vector<int>> tree;
queue<TreeNode*> q;
q.push(root);
while(!q.empty())
{
int size=q.size();//每层有多少个节点数
vector<int> level;
while(size--)
{
TreeNode *node=q.front();
q.pop();
level.push_back(node->val);
if(node->left)
q.push(node->left);
if(node->right)
q.push(node->right);
}
tree.push_back(level);
}
return tree;
}
};
二叉树的层次遍历 II
给定一个二叉树,返回其节点值自底向上的层次遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)
例如:
给定二叉树 [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回其自底向上的层次遍历为:
[
[15,7],
[9,20],
[3]
]
思路:
跟上一题只需要修改一下插入的位置就行了。将每一层的push改成insert
/**
* 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>> levelOrderBottom(TreeNode* root) {
if(!root)
return {};
vector<vector<int>> tree;
queue<TreeNode*> q;
q.push(root);
while(!q.empty())
{
int size=q.size();//每层有多少个节点数
vector<int> level;
while(size--)
{
TreeNode *node=q.front();
q.pop();
level.push_back(node->val);
if(node->left)
q.push(node->left);
if(node->right)
q.push(node->right);
}
tree.insert(tree.begin(),level);
}
return tree;
}
};
将有序数组转换为二叉搜索树
将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。
示例:
给定有序数组: [-10,-3,0,5,9],
一个可能的答案是:[0,-3,9,-10,null,5],它可以表示下面这个高度平衡二叉搜索树:
0
/ \
-3 9
/ /
-10 5
c++代码
思路:
采用二分查找,最中间的数作为根节点,左半部分的中间的数作为根节点的左节点,右半部分中间的数作为根节点的右节点。
/**
* 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* sortedArrayToBST(vector<int>& nums) {
if(nums.empty())
return NULL;
int n=nums.size();
return getTree(nums,0,n-1);
}
TreeNode* getTree(vector<int>& nums,int low,int high)
{
if(low>high)
return NULL;
int mid=low+(high-low)/2;
TreeNode* node = new TreeNode(nums[mid]);
node->left=getTree(nums,low,mid-1);
node->right=getTree(nums,mid+1,high);
return node;
}
};