对称二叉树
class Solution {
public:
bool cmp(TreeNode* l,TreeNode* r){
if(l==NULL&&r==NULL){//排除空子结点
return 1;
}
else if(l!=NULL&&r!=NULL&&l->val==r->val){//唯一能递归的条件
bool outside=cmp(l->left,r->right);
bool inside=cmp(l->right,r->left);
return outside&&inside;
}
else return 0;//左右结点一个为空一个不为空,或者数值不相等
}
bool isSymmetric(TreeNode* root) {
if(root==NULL){
return 1;
}
return cmp(root->left,root->right);
}
};
完全二叉树的节点个数
class Solution {
public:
int countNodes(TreeNode* root) {
queue<TreeNode*> q;
if(root!=NULL){
q.push(root);
}
int res=0;
while(!q.empty()){
int size=q.size();//因为q的大小是不断变化的,所以先存起来
for(int i=0;i<size;i++){
TreeNode* cur=q.front();
q.pop();
res++;
if(cur->left){//下一层的元素按顺序入队列
q.push(cur->left);
}
if(cur->right){
q.push(cur->right);
}
}
}
return res;
}
};
平衡二叉树
class Solution {
public:
int getDepth(TreeNode* node) {
if (node == NULL) {
return 0;
}
int leftDepth = getDepth(node->left);
if (leftDepth == -1) return -1; // 说明左子树已经不是二叉平衡树
int rightDepth = getDepth(node->right);
if (rightDepth == -1) return -1; // 说明右子树已经不是二叉平衡树
return abs(leftDepth - rightDepth) > 1 ? -1 : 1 + max(leftDepth, rightDepth);
}
bool isBalanced(TreeNode* root) {
return getDepth(root) == -1 ? false : true;
}
};
二叉树的所有路径
class Solution {
public:
void traversal(TreeNode* cur,string path,vector<string>& res){
path+=to_string(cur->val);//前序遍历 中
if(cur->left==NULL&&cur->right==NULL){//叶子节点
res.push_back(path);
return;
}
if(cur->left){
traversal(cur->left,path+"->",res);//左
}
//path + "->"这里隐藏了回溯,传值是path+="->",但path没改变
if(cur->right){
traversal(cur->right,path+"->",res);//右
}
}
vector<string> binaryTreePaths(TreeNode* root) {
vector<string> res;
string path;
if(root==NULL){
return res;
}
traversal(root,path,res);
return res;
}
};
左叶子之和
凡是递归能做的栈也能做
class Solution {
public:
int sumOfLeftLeaves(TreeNode* root) {
stack<TreeNode*> s;
if(root==NULL){
return 0;
}
s.push(root);
int res=0;
while(!s.empty()){
TreeNode* cur=s.top();
s.pop();
if(cur->left!=NULL && cur->left->left==NULL && cur->left->right==NULL){
res+=cur->left->val;
}//通过父结点判断
if(cur->right){
s.push(cur->right);
}
if(cur->left){//慢入先出
s.push(cur->left);
}
}
return res;
}
};
找树左下角的值
class Solution {
public:
int findBottomLeftValue(TreeNode* root) {
queue<TreeNode*> q;
if(root!=NULL){
q.push(root);
}
int res=0;
while(!q.empty()){
int size=q.size();
for(int i=0;i<size;i++){
TreeNode* cur=q.front();
q.pop();
if(i==0){//层序遍历,到最后就是最后一层
res=cur->val;
}
if(cur->left){
q.push(cur->left);
}
if(cur->right){
q.push(cur->right);
}
}
}
return res;
}
};
路径总和
class Solution {
public:
bool hasPathSum(TreeNode* root, int targetSum) {
if(root==NULL){
return 0;
}
stack<pair<TreeNode*,int>> s;
s.push(pair<TreeNode*,int>(root,root->val));
while(!s.empty()){
pair<TreeNode*,int> cur=s.top();
s.pop();
if((!cur.first->left) && (!cur.first->right) && targetSum==cur.second){
return 1;
}
if(cur.first->right){
s.push(pair<TreeNode*,int>(cur.first->right,cur.second+cur.first->right->val));
}
if(cur.first->left){
s.push(pair<TreeNode*,int>(cur.first->left,cur.second+cur.first->left->val));
}
}
return 0;
}
};
从中序与后序遍历序列构造二叉树
坚持左闭右开区间
效率较低,但容易理解点
class Solution {
public:
TreeNode* traversal(vector<int>& inorder,vector<int>& postorder){
if(postorder.size()==0){
return NULL;
}
int rootValue=postorder[postorder.size()-1];
TreeNode* root=new TreeNode(rootValue);
//处理叶子节点,递归结束
if(postorder.size()==1){
return root;
}
//切割中序数组
int mid;
for(mid=0;mid<inorder.size();mid++){
if(inorder[mid]==rootValue){
break;
}
}
vector<int> linorder(inorder.begin(),inorder.begin()+mid);
vector<int> rinorder(inorder.begin()+mid+1,inorder.end());//+1跳过root
//切割后序数组
postorder.resize(postorder.size()-1);
vector<int> lpostorder(postorder.begin(),postorder.begin()+linorder.size());
vector<int> rpostorder(postorder.begin()+linorder.size(),postorder.end());
//递归
root->left=traversal(linorder,lpostorder);
root->right=traversal(rinorder,rpostorder);
return root;
}
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
if(inorder.size()==0||postorder.size()==0){
return NULL;
}
return traversal(inorder,postorder);
}
};
从前序与中序遍历序列构造二叉树
最大二叉树
class Solution {
public:
TreeNode* traversal(vector<int>& nums,int left,int right){
if(left>=right){
return NULL;//遇到空结点结束递归,即数组为空
}
int maxIndex=left;
for(int i=left+1;i<right;i++){
if(nums[i]>nums[maxIndex]){
maxIndex=i;
}
}
TreeNode* root=new TreeNode(nums[maxIndex]);//中
root->left=traversal(nums,left,maxIndex);//左
root->right=traversal(nums,maxIndex+1,right);//右
return root;
}
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
return traversal(nums,0,nums.size());
}
};
合并二叉树
递归法
class Solution {
public:
TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
if(root1==NULL){
return root2;
}
if(root2==NULL){
return root1;
}
root1->val+=root2->val;
root1->left=mergeTrees(root1->left,root2->left);
root1->right=mergeTrees(root1->right,root2->right);
return root1;
}
};
迭代法
class Solution {
public:
TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
if(root1==NULL){
return root2;
}
if(root2==NULL){
return root1;
}
queue<TreeNode*> q;
q.push(root1);
q.push(root2);
while(!q.empty()){
TreeNode* cur1=q.front();
q.pop();
TreeNode* cur2=q.front();
q.pop();
cur1->val+=cur2->val;
if(cur1->left&&cur2->left){
q.push(cur1->left);
q.push(cur2->left);
}
if(cur1->right&&cur2->right){
q.push(cur1->right);
q.push(cur2->right);
}
if(cur1->left==NULL&&cur2->left){
cur1->left=cur2->left;
}
if(cur1->right==NULL&&cur2->right){
cur1->right=cur2->right;
}
}
return root1;
}
};