目录
17. LeetCode101. 对称二叉树
思路:
1.本质上就是在判断每个节点的左右子树翻转后是否和原先一样
2.以对称轴为中心轴,内侧和内侧的比较、外侧和外侧的比较
3.确定遍历顺序:only后序(左右中),因为我们需要左右子树的信息,才能判断是否能够翻转
递归:并非传统的向左右子节点要信息,而是向两个应当匹配的节点索要信息
class Solution {
public:
bool compare(TreeNode*compareLeft,TreeNode*compareRight){
//base case(确保非空后才可判断值)
//前三种情况是判断结构,最后一种情况是判断值
if(compareLeft!=NULL&&compareRight==NULL)return false;
else if(compareLeft==NULL&&compareRight!=NULL)return false;
else if(compareLeft==NULL&&compareRight==NULL)return true;
else if(compareLeft->val!=compareRight->val)return false;
//索要内侧和外侧的信息
bool inside=compare(compareLeft->right,compareRight->left);
bool outside=compare(compareLeft->left,compareRight->right);
//只有当内侧和外侧的节点都符合要求时,整体才对称
return inside&&outside;
}
bool isSymmetric(TreeNode* root) {
return compare(root->left,root->right);
}
};
迭代:
class Solution {
public:
bool isSymmetric(TreeNode* root) {
queue<TreeNode*>que;
que.push(root->left);
que.push(root->right);
while(!que.empty()){
//取出的两个节点是将要匹配的
TreeNode*compareLeft=que.front();que.pop();
TreeNode*compareRight=que.front();que.pop();
if(!compareLeft&&!compareRight)continue;
else if(!compareLeft||!compareRight||compareLeft->val!=compareRight->val)return false;
//由于是按序取,所以也要按序存
que.push(compareLeft->right);
que.push(compareRight->left);
que.push(compareLeft->left);
que.push(compareRight->right);
}
return true;
}
};
18. LeetCode222. 完全二叉树的节点个数
1.当作普通二叉树:
class Solution {
public:
int countNodes(TreeNode* root) {
if(root==NULL)return 0;
int leftNodes=countNodes(root->left);
int rightNodes=countNodes(root->right);
return leftNodes+rightNodes+1;
}
};
2.利用完全二叉树的特性:
2.1如果子树是完全满二叉树,利用公式(2^h-1)直接得出节点个数
2.2判断完全满二叉树:在完全二叉树的基础上,一直向左遍历的深度等于一直向右遍历的深度,就说明是完全满二叉树
class Solution {
public:
int countNodes(TreeNode* root) {
//base case
if(root==NULL)return 0;
//和普通二叉树唯一的区别:多了一步判断完全满二叉树,可以少遍历中间节点
TreeNode*left=root->left;
TreeNode*right=root->right;
int leftDepth=0;
int rightDepth=0;
while(left){
left=left->left;
leftDepth++;
}
while(right){
right=right->right;
rightDepth++;
}
if(leftDepth==rightDepth){
return (2<<leftDepth)-1;
}
//当前节点逻辑
int leftNodes=countNodes(root->left);
int rightNodes=countNodes(root->right);
return leftNodes+rightNodes+1;
}
};
19. LeetCode110. 平衡二叉树
class Solution {
public:
class Info{
public:
bool isBalanced;
int height;
Info(bool isBalanced,int height){
this->isBalanced=isBalanced;
this->height=height;
}
};
Info process(TreeNode*node){
if(node==NULL)return Info(true,0);
//向左右子树索要信息
Info leftData=process(node->left);
Info rightData=process(node->right);
//处理当前节点信息
bool isBalanced=(abs(leftData.height-rightData.height)<=1
&&leftData.isBalanced
&&rightData.isBalanced);
int height=max(leftData.height,rightData.height)+1;
return Info(isBalanced,height);
}
bool isBalanced(TreeNode* root) {
Info data=process(root);
return data.isBalanced;
}
};
20. LeetCode257. 二叉树的所有路径
递归:
class Solution {
public:
vector<string>res;
void process(TreeNode*node,string path){
if(node==NULL){
return;
}
if(node->left==NULL&&node->right==NULL){//遍历到叶子节点才停止
res.push_back(path+to_string(node->val));
return;
}
process(node->left,path+to_string(node->val)+"->");
process(node->right,path+to_string(node->val)+"->");
}
vector<string> binaryTreePaths(TreeNode* root) {
process(root,"");
return res;
}
};
迭代:
class Solution {
public:
vector<string> binaryTreePaths(TreeNode* root) {
stack<TreeNode*>treeStk;//保存树的节点
stack<string>pathStk;//保留路径
vector<string>res;//最终路径集合
treeStk.push(root);
pathStk.push(to_string(root->val));
while(!treeStk.empty()){
TreeNode*node=treeStk.top();treeStk.pop();//取出该节点
string path=pathStk.top();pathStk.pop();//取出该节点对应路径
if(node->left==NULL&&node->right==NULL){//叶子节点
res.push_back(path);
}
if(node->right){//栈:右先
treeStk.push(node->right);
pathStk.push(path+"->"+to_string(node->right->val));
}
if(node->left){
treeStk.push(node->left);
pathStk.push(path+"->"+to_string(node->left->val));
}
}
return res;
}
};