1. 判断相同
100. 相同的树
class Solution {
public:
bool isSameTree(TreeNode* p, TreeNode* q) {
if(!p&&!q) return true;
if(!p||!q) return false;
if(p->val!=q->val) return false;
return isSameTree(p->left,q->left)&&isSameTree(p->right,q->right);
}
};
101. 对称二叉树
class Solution {
public:
bool isSame(TreeNode* p,TreeNode* q){
if(!p&&!q) return true;
if(!p||!q) return false;
if(p->val!=q->val) return false;
return isSame(p->left,q->right)&&isSame(p->right,q->left);
}
bool isSymmetric(TreeNode* root) {
return isSame(root,root);
}
};
2. 翻转
226. 翻转二叉树
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
if(!root) return NULL;
TreeNode* left=invertTree(root->left);
TreeNode* right=invertTree(root->right);
root->left=right;
root->right=left;
return root;
}
};
3. 深度
111. 二叉树的最小深度
class Solution {
public:
int minDepth(TreeNode* root) {
if(!root) return 0;
int left_minDepth=minDepth(root->left);
int right_minDepth=minDepth(root->right);
if(!left_minDepth&&!right_minDepth) return 1;
else if(!left_minDepth&&right_minDepth) return right_minDepth+1;
else if(left_minDepth&&!right_minDepth) return left_minDepth+1;
return min(left_minDepth,right_minDepth)+1;
}
};
104. 二叉树的最大深度
class Solution {
public:
int maxDepth(TreeNode* root) {
if(!root) return 0;
return max(maxDepth(root->left),maxDepth(root->right))+1;
}
};
543. 二叉树的直径
class Solution {
public:
int res=0;
int maxHeight(TreeNode* root){ //返回树的高度
if(!root) return 0;
int left_height=maxHeight(root->left);
int right_height=maxHeight(root->right);
res=max(res,left_height+right_height);
return max(left_height,right_height)+1;
}
int diameterOfBinaryTree(TreeNode* root) {
maxHeight(root);
return res;
}
};
4. 遍历
144. 二叉树的前序遍历
class Solution {
public:
void travel(TreeNode* root,vector<int>& res){
if(!root) return;
res.push_back(root->val);
travel(root->left,res);
travel(root->right,res);
}
vector<int> preorderTraversal(TreeNode* root) {
vector<int> res;
travel(root,res);
return res;
}
};
class Solution {
public:
vector<int> travel(TreeNode* root){
vector<int> res;
stack<TreeNode*> stk;
while(root||!stk.empty()){
while(root){
res.push_back(root->val);
stk.push(root);
root=root->left;
}
root=stk.top();
stk.pop();
root=root->right;
}
return res;
}
vector<int> preorderTraversal(TreeNode* root) {
return travel(root);
}
};
145. 二叉树的后序遍历
class Solution {
public:
vector<int> res;
void travel(TreeNode* root){
if(!root) return;
travel(root->left);
travel(root->right);
res.push_back(root->val);
}
vector<int> postorderTraversal(TreeNode* root) {
travel(root);
return res;
}
};
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
vector<int> res;
stack<TreeNode*> stk;
TreeNode* prev;
while(root||!stk.empty()){
while(root){ //先把最左的节点一路入栈
stk.push(root);
root=root->left;
}
root=stk.top();
stk.pop();
if(!root->right||prev==root->right){
prev=root;
res.push_back(root->val);
root=NULL;
}else{
stk.push(root);
root=root->right;
}
}
return res;
}
};
94. 二叉树的中序遍历
class Solution {
public:
void travel(TreeNode* root,vector<int>& res){
if(!root) return;
travel(root->left,res);
res.push_back(root->val);
travel(root->right,res);
}
vector<int> inorderTraversal(TreeNode* root) {
vector<int> res;
travel(root,res);
return res;
}
};
class Solution {
public:
vector<int> travel(TreeNode* root){
vector<int> res;
stack<TreeNode*> stk;
while(root||!stk.empty()){
while(root!=NULL){
stk.push(root);
root=root->left;
}
root=stk.top();
stk.pop();
res.push_back(root->val);
root=root->right;
}
return res;
}
vector<int> inorderTraversal(TreeNode* root) {
return travel(root);
}
};
102. 二叉树的层序遍历
class Solution {
public:
vector<vector<int>> res;
void search(TreeNode* root){
queue<TreeNode*> q;
queue<int> idx;
q.push(root);
idx.push(1);
while(!q.empty()){
TreeNode* p=q.front();
q.pop();
int i=idx.front();
idx.pop();
if(res.size()<i) res.push_back({});
res[i-1].push_back(p->val);
cout<<i<<":"<<p->val<<endl;
if(p->left){
q.push(p->left);
idx.push(i+1);
}
if(p->right){
q.push(p->right);
idx.push(i+1);
}
}
}
vector<vector<int>> levelOrder(TreeNode* root) {
if(!root) return res;
search(root);
return res;
}
};
199. 二叉树的右视图
class Solution {
public:
vector<vector<int>> res;
void search(TreeNode* root){
queue<TreeNode*> q;
queue<int> idx;
q.push(root);
idx.push(1);
while(!q.empty()){
TreeNode* p=q.front();
q.pop();
int i=idx.front();
idx.pop();
if(res.size()<i) res.push_back({});
res[i-1].push_back(p->val);
cout<<i<<":"<<p->val<<endl;
if(p->left){
q.push(p->left);
idx.push(i+1);
}
if(p->right){
q.push(p->right);
idx.push(i+1);
}
}
}
vector<int> rightSideView(TreeNode* root) {
vector<int> final_res;
if(!root) return final_res;
search(root);
for(int i=0;i<res.size();i++){
final_res.push_back(res[i][res[i].size()-1]);
}
return final_res;
}
};
5. 恢复二叉树
105. 从前序与中序遍历序列构造二叉树
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if(preorder.size()==0) return NULL;
int idx=-1;
for(int i=0;i<inorder.size();i++){
if(inorder[i]==preorder[0]){
idx=i; //找到左右子树的分叉点(即根节点)
break;
}
}
TreeNode* p=new TreeNode(inorder[idx]);
cout<<inorder[idx];
vector<int> pre_left(preorder.begin()+1,preorder.begin()+idx+1); //preleft=preorder[1,idx] 要排除掉第0个(即根节点)
vector<int> pre_right(preorder.begin()+idx+1,preorder.end());
vector<int> in_left(inorder.begin(),inorder.begin()+idx); //不用排除掉第0个, 但要排除掉idx
vector<int> in_right(inorder.begin()+idx+1,inorder.end());
p->left=buildTree(pre_left,in_left);
p->right=buildTree(pre_right,in_right);
return p;
}
};
889. 根据前序和后序遍历构造二叉树
class Solution {
public:
TreeNode* constructFromPrePost(vector<int>& preorder, vector<int>& postorder) {
if(preorder.size()==0) return NULL;
if(preorder.size()==1){
TreeNode* p=new TreeNode(preorder[0]);
return p;
}
int idx=-1; //后序遍历序列中, idx及其左边为左子树, 右边为右子树
for(int i=0;i<postorder.size();i++){
if(postorder[i]==preorder[1]){
idx=i;
break;
}
}
TreeNode* p=new TreeNode(preorder[0]);
vector<int> left_pre(preorder.begin()+1,preorder.begin()+idx+2);
vector<int> right_pre(preorder.begin()+idx+2,preorder.end());
vector<int> left_post(postorder.begin(),postorder.begin()+idx+1);
vector<int> right_post(postorder.begin()+idx+1,postorder.end()-1);
p->left=constructFromPrePost(left_pre,left_post);
p->right=constructFromPrePost(right_pre,right_post);
return p;
}
};
108. 将有序数组转换为二叉搜索树
class Solution {
public:
TreeNode* sortedArrayToBST(vector<int>& nums) {
if(nums.size()==0) return NULL;
int l=0,r=nums.size()-1,mid=(l+r)/2;
TreeNode* p=new TreeNode(nums[mid]);
vector<int> left_nums(nums.begin(),nums.begin()+mid);
vector<int> right_nums(nums.begin()+mid+1,nums.end());
p->left=sortedArrayToBST(left_nums);
p->right=sortedArrayToBST(right_nums);
return p;
}
};
6. 路径总和
112. 路径总和
class Solution {
public:
vector<int> res;
bool helper(TreeNode* root,int sum,int targetSum){
if(!root) return false;
if(!root->left&&!root->right){
sum+=root->val;
return sum==targetSum;
}
sum+=root->val;
return helper(root->left,sum,targetSum)||helper(root->right,sum,targetSum);
}
bool hasPathSum(TreeNode* root, int targetSum) {
return helper(root,0,targetSum);
}
};
113. 路径总和 II
class Solution {
public:
vector<int> path;
vector<vector<int>> res;
void helper(TreeNode* root, int sum,int targetSum){
if(!root) return;
if(!root->left&&!root->right){
sum+=root->val;
path.push_back(root->val);
if(sum==targetSum) res.push_back(path);
path.pop_back();
}else{
sum+=root->val;
path.push_back(root->val);
helper(root->left,sum,targetSum);
helper(root->right,sum,targetSum);
path.pop_back();
}
}
vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
helper(root,0,targetSum);
return res;
}
};
437. 路径总和 III
class Solution {
public:
unordered_map<long long,int> prefix; //存储根节点到每一个节点的路径长度, 后用前缀和就可以求出所有节点之间的路经长度
int helper(TreeNode* root,long long sum,int targetSum){
if(!root) return 0;
int cnt=0; //满足条件的路径总数
sum+=root->val;
if(prefix.find(sum-targetSum)!=prefix.end()){
cnt=prefix[sum-targetSum];
}
prefix[sum]++;
cnt+=helper(root->left,sum,targetSum);
cnt+=helper(root->right,sum,targetSum);
prefix[sum]--;
return cnt;
}
int pathSum(TreeNode* root, int targetSum) {
prefix[0]=1;
return helper(root,0,targetSum);
}
};
7.else
114. 二叉树展开为链表
class Solution {
public:
void flatten(TreeNode* root) {
if(!root) return;
TreeNode* prev=NULL;
TreeNode* head=root;
while(head){
if(head->left){ //左子树存在的话, 找到左子树中的最右节点
prev=head->left;
while(prev->right) prev=prev->right;
prev->right=head->right;
head->right=head->left;
head->left=NULL;
}
head=head->right;
}
}
};
236. 二叉树的最近公共祖先
class Solution {
public:
vector<TreeNode*> path2p;
vector<TreeNode*> path2q;
bool findPath(TreeNode* root,TreeNode* p,vector<TreeNode*>& path){
if(!root) return false;
path.push_back(root);
if(root==p){
return true;
}
bool isFind=false;
if(!isFind){
isFind=findPath(root->left,p,path);
}
if(!isFind){
isFind=findPath(root->right,p,path);
}
if(!isFind) path.pop_back();
return isFind;
}
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
findPath(root,p,path2p);
findPath(root,q,path2q);
for(int i=path2p.size()-1;i>=0;i--){
for(int j=path2q.size()-1;j>=0;j--){
if(path2p[i]->val==path2q[j]->val) return path2p[i];
}
}
return NULL;
}
};