写在前面
刚开始写博客,希望大家多多支持哈,我的个人动态博客网站链接:flamsteed,在CSDN上面同步更新。
最近做了一些题目,发现dfs竟有些生疏了,所以就到leetcode的dfs分类下面刷题,然后发现二叉树也生疏了=.= 做了几题,感觉值得整理一下,可以加深对二叉树的理解与应用。
另外关于所有二叉树的定义如下:
//Definition for a binary tree node.
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
LeetCode 100. Same Tree
Given two binary trees, write a function to check if they are the same or not.
Two binary trees are considered the same if they are structurally identical and the nodes have the same value.
题目大意:判断输入的两棵二叉树是否完全相等
解法:虽然题目很简单,但是本着练习的目的,还是要认真做一下,这里可以有两种做法,recursion和iteration。
(一)recursion:
递归解法思路很简单,递归判断p->left和q->left,p->right和q->right是否是相等的子树。
代码:
class Solution {
public:
bool isSameTree(TreeNode* p, TreeNode* q) {
if(p && q){
if(p->val==q->val){
return ((isSameTree(p->left,q->left))&&(isSameTree(p->right,q->right)));
}
else return false;
}
else if(p==NULL && q==NULL){
return true;
}
else return false;
}
};
(二)iteration:
迭代代码量大一些,用循环代替了函数的递归调用,用队列(vector数组也可以)暂存满足条件的左右孩子。
class Solution {
public:
bool isSameTree(TreeNode* p, TreeNode* q) {
if (p == NULL && q == NULL) return true;
if (p == NULL || q == NULL) return false;
TreeNode *curp = NULL, *curq = NULL;
queue<TreeNode *>qp;
queue<TreeNode *>qq;
qp.push(p);
qq.push(q);
while (!qp.empty() && !qq.empty())
{
curp = qp.front();
qp.pop();
curq = qq.front();
qq.pop();
if (curp == NULL && curq == NULL)
continue;
if (curp && curq)
{
if (curp->val != curq->val) return false;
qp.push(curp->left);
qp.push(curp->right);
qq.push(curq->left);
qq.push(curq->right);
}
else
return false;
}
if (qp.empty() && qq.empty())
return true;
return false;
}
};
101. Symmetric Tree
Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center).
题目大意:判断一棵二叉树是不是左右对称的。
解法:判断一个节点的左子树和右子树是否对称即可,同样是递归和迭代两种解法,这里就写recursion一种了。
代码:
class Solution {
public:
bool isSymmetric(TreeNode* root) {
if(root == NULL) return true;
return(isSametree(root->left,root->right));
}
bool isSametree(TreeNode* p, TreeNode* q){
if(p && q){
if(p->val==q->val){
return ((isSametree(p->left,q->right))&&(isSametree(p->right,q->left)));
}
else return false;
}
else if(p==NULL && q==NULL){
return true;
}
else{
return false;
}
}
};
102. Binary Tree Level Order Traversal
Given a binary tree, return the level order traversal of its nodes’ values. (ie, from left to right, level by level).
题目大意:把输入的二叉树按层存放在二维数组里面,根的层数为0,存放在第0行。这题难度较前两题稍微加大了一点,所以用两种解法来做,加以练习。
(一)recursion
class Solution {
public:
vector<vector<int>> res;
vector<vector<int>> levelOrder(TreeNode* root) {
if(root==NULL) return res;
helper(root,0);
vector<vector<int>> ans;
for(int i=0; i<res.size(); i++){
if(!res[i].size()) break;
ans.push_back({});
for(int j=0; j<res[i].size(); j++)
ans[i].push_back(res[i][j]);
}
return ans;
}
void helper(TreeNode* node, int level){
res.push_back({});
res[level].push_back(node->val);
if(node->left!=NULL)
helper(node->left,level+1);
if(node->right!=NULL)
helper(node->right,level+1);
}
};
(二)iteration
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> levels;
if(root==NULL) return levels;
queue<TreeNode*> q;
q.push(root);
int level = 0;
while(!q.empty()){
levels.push_back({});
int level_length = q.size();
for(int i=0; i<level_length; i++){
TreeNode* node = q.front();
q.pop();
levels[level].push_back(node->val);
if(node->left!=NULL) q.push(node->left);
if(node->right!=NULL) q.push(node->right);
}
level++;
}
return levels;
}
};
104. Maximum Depth of Binary Tree
Given a binary tree, find its maximum depth.
The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.
题目大意:求出一棵二叉树的最大深度,根深度为1.
解法: 递归左子树和右子树的深度然后返回最大的一个就行了。
代码:
class Solution {
public:
int ans;
int maxDepth(TreeNode* root) {
if(root==NULL) return 0;
return max(1+maxDepth(root->left),1+maxDepth(root->right));
}
};
105. Construct Binary Tree from Preorder and Inorder Traversal
Given preorder and inorder traversal of a tree, construct the binary tree.
题目大意:给出一棵二叉树的前序和中序便利的数组,求这棵树。
解法:preorder从左开始就是根节点,然后在inorder里面找到这个点的位置,左边就是这个根节点的左子树,右边就是右子树,然后分别再左右递归往下找,同时构建二叉树即可。
代码:
class Solution {
public:
int findIndex(vector<int>& inorder, int is, int ie, int key){//寻找在inorder数组里的位置
int index = 0;
for(int i=is; i<=ie; i++)
if(inorder[i]==key){
index = i;
break;
}
return index;
}
TreeNode* helper(vector<int>& inorder, int is, int ie, vector<int>& preorder, int ps){
if(is>ie || ps<0) return NULL;//边界条件
TreeNode* node = new TreeNode(preorder[ps]);
int index = findIndex(inorder, is, ie, preorder[ps]);
node->left = helper(inorder, is, index-1, preorder, ps+1);
node->right= helper(inorder, index+1, ie, preorder, ps+index-is+1);
return node;
}
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if(preorder.empty()||inorder.empty())
return NULL;
return helper(inorder,0,inorder.size()-1,preorder,0);
}
};
106. Construct Binary Tree from Inorder and Postorder Traversal
Given inorder and postorder traversal of a tree, construct the binary tree.
题目大意:给出中序和后序遍历,求二叉树。
解法:方法和给出前序和中序的类似,倒着从后序遍历的数组往前,然后在中序里面找到根。
代码:
class Solution {
public:
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
return bld(inorder,postorder,0,inorder.size()-1,0,postorder.size()-1);
}
TreeNode* bld(vector<int>&inorder, vector<int>&postorder, int istart, int iend,
int pstart,int pend){
if(istart > iend || pstart > pend)
return NULL;
int val = postorder[pend];
int i = istart;
while(inorder[i] != val) i++;
TreeNode* root = new TreeNode(val);
root->left = bld(inorder, postorder, istart, i-1, pstart, pstart+i-istart-1);
root->right = bld(inorder, postorder, i+1, iend, pend-(iend-i), pend-1);
return root;
}
};
110. Balanced Binary Tree
Given a binary tree, determine if it is height-balanced.
For this problem, a height-balanced binary tree is defined as:
a binary tree in which the left and right subtrees of every node differ in height by no more than 1.
题目大意:判断输入的二叉树是不是平衡二叉树(左右子树高度差<=1)。
解法: 先定义每个节点的高度,height§ = 1 + max(height(p->left),height(p->right)),当p点为空时,返回值为-1。
然后再比较左右子树的height差值并判断就行了,伪代码如下:
isBalanced(root):
if (root == NULL):
return true
if (abs(height(root.left) - height(root.right)) > 1):
return false
else:
return isBalanced(root.left) && isBalanced(root.right)
整个的代码:
class Solution {
public:
bool isBalanced(TreeNode* root) {
if(root==NULL)
return true;
return abs(height(root->left)-height(root->right))<2 && isBalanced(root->left) && isBalanced(root->right);
}
int height(TreeNode* root){
if(root==NULL)
return -1;
return 1 + max(height(root->left),height(root->right));
}
};