二叉树

字符串转int

(5条消息) c++中的atoi()和stoi()函数的用法和区别_鸡啄米的时光机的博客-CSDN博客_stoi

int转字符串  

s=to_string(root->val);

 

递归三部曲,1确定递归函数参数和返回值;2确定终止条件;3确定单层逻辑

三种基本遍历,不仅递归要会,用栈迭代遍历也要会

144. 二叉树的前序遍历 - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {
 2 public:
 3     void f(TreeNode* root,vector<int>&result){
 4         if(!root)
 5             return ;
 6         result.push_back(root->val);
 7         f(root->left,result);
 8         f(root->right,result);
 9     }
10     vector<int> preorderTraversal(TreeNode* root) {
11         vector<int> result;
12         f(root,result);
13         return result;
14     }
15 };
View Code

94. 二叉树的中序遍历 - 力扣(LeetCode) (leetcode-cn.com)

145. 二叉树的后序遍历 - 力扣(LeetCode) (leetcode-cn.com)

102. 二叉树的层序遍历 - 力扣(LeetCode) (leetcode-cn.com)

这道题忘记队列的size()方法可以获取长度了

class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        vector<vector<int>> ans;
        queue<TreeNode*> q;
        if(!root)
            return ans;
        q.push(root);
        while(!q.empty()){
            vector<int> a;
            int n = q.size();//划重点队列大小会变,所以赶紧存下来
            for(int i=0;i<n;++i){
                TreeNode* t= q.front();
                a.push_back(t->val);
                q.pop();
                if(t->left)
                    q.push(t->left);
                if(t->right)
                    q.push(t->right);
            }
            ans.push_back(a);
        }
        return ans;
    }
};
View Code

226. 翻转二叉树 - 力扣(LeetCode) (leetcode-cn.com)

class Solution {
public:
    void f(TreeNode* &root){
        if(!root)
            return ;
        swap(root->left,root->right);
        f(root->left);
        f(root->right);
    }
    TreeNode* invertTree(TreeNode* root) {
        f(root);
        return root;
    }
};
View Code

 101. 对称二叉树 - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {
 2 public:
 3     bool f(TreeNode* root1,TreeNode* root2){
 4         if(!root1&&!root2)
 5             return true;
 6         else if(!root1&&root2)
 7             return false;
 8         else if(root1&&!root2)
 9             return false;
10         else if(root1->val!=root2->val)
11             return false;
12         return f(root1->left,root2->right)&&f(root1->right,root2->left);
13     }
14     bool isSymmetric(TreeNode* root) {
15         if(!root)
16             return true;
17         return f(root->left,root->right);
18     }
19 };
View Code

 104. 二叉树的最大深度 - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {
 2 public:
 3     int getDepth(TreeNode* root,int depth){
 4         if(!root)
 5             return depth;
 6         return max(getDepth(root->left,depth+1),getDepth(root->right,depth+1));
 7     }
 8     int maxDepth(TreeNode* root) {
 9         return getDepth(root,0);
10     }
11 };
View Code

 111. 二叉树的最小深度 - 力扣(LeetCode) (leetcode-cn.com)

class Solution {
public:
    int getDepth(TreeNode* root,int depth){
        if(!root)
            return 1e5;
        if(root&&!root->left&&!root->right)
            return depth+1;
        return min(getDepth(root->left,depth+1),getDepth(root->right,depth+1));
    }
    int minDepth(TreeNode* root) {
        if(!root)
            return 0 ;
        return getDepth(root,0);
    }
};
View Code

 110. 平衡二叉树 - 力扣(LeetCode) (leetcode-cn.com)

自顶而下解法,最差情况一条链O(n^2)

 1 class Solution {
 2 public:
 3     int getDepth(TreeNode* root,int depth){
 4         if(!root)
 5             return depth;
 6         return max(getDepth(root->left,depth+1),getDepth(root->right,depth+1));
 7     }
 8     bool isBalanced(TreeNode* root) {
 9         if(!root)
10             return true;
11         if(abs(getDepth(root->left,0)-getDepth(root->right,0))>1){//符号与)位置
12             return false;
13         }
14             
15         return isBalanced(root->left)&&isBalanced(root->right);
16     }
17 };
View Code

 后序遍历O(n)深度,root值最小为1

 1 class Solution {
 2 public:
 3     bool result = true;
 4     int getDepth(TreeNode* root,int depth){
 5         if(!root)
 6             return depth;
 7         int leftDepth = getDepth(root->left,depth+1);
 8         int rightDepth = getDepth(root->right,depth+1);
 9         if(abs(leftDepth-rightDepth)>1){
10             result =false;
11             return 0;
12         }    
13         return max(leftDepth,rightDepth);
14     }
15     bool isBalanced(TreeNode* root) {
16         getDepth(root,0);
17         return result;
18     }
19 };
View Code

后续遍历O(n)高度,root值最大

 1 class Solution {
 2 public:
 3     int getHeight(TreeNode* root){//高度写法,根的高度最高数值最大,最底下叶子节点为1,和深度反着,深度是根这为1,叶子最底下节点最大。看那个+1是从上往下传还是从下往上
 4         if(!root)
 5             return 0;
 6         int leftHeight = getHeight(root->left);
 7         int rightHeight = getHeight(root->right);
 8         if(leftHeight==-1||rightHeight==-1||abs(leftHeight-rightHeight)>1){//中间子树出错,要传递错误到根,和全局变量写法不一样
 9             return -1;
10         }    
11         return max(leftHeight,rightHeight)+1;
12     }
13     bool isBalanced(TreeNode* root) {
14         return getHeight(root)!=-1;
15     }
16 };
View Code

 257. 二叉树的所有路径 - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {
 2 public:
 3     vector<string> result;
 4     void f(TreeNode* root,string s){
 5         if(!root)
 6             return ;
 7         if(root!=nullptr&&root->left==nullptr&&root->right==nullptr){
 8             s = s==""?to_string(root->val):s+="->"+to_string(root->val);
 9             result.push_back(s);
10             s = "";
11             return ;
12         }
13         s = s==""?to_string(root->val):s+="->"+to_string(root->val);
14         f(root->left,s);
15         f(root->right,s);
16     }
17     vector<string> binaryTreePaths(TreeNode* root) {
18         string s = "";
19         f(root,s);
20         return result;
21     }
22 };
View Code

 112. 路径总和 - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {
 2 public:
 3     bool  result = false;
 4     void f(TreeNode* root, int targetSum){
 5         if(root==nullptr)
 6             return ;
 7         targetSum -= root->val;
 8         if(root->left==nullptr&&root->right==nullptr&&targetSum == 0){
 9             result = true;
10             return ;
11         }
12         f(root->left,targetSum);
13         f(root->right,targetSum);
14     }
15     bool hasPathSum(TreeNode* root, int targetSum) {
16         if(!root)
17             return false;
18         f(root,targetSum);
19         return result;
20     }
21 };
View Code

 113. 路径总和 II - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {
 2 public:
 3     vector<vector<int>> result;
 4     void f(TreeNode* root, int targetSum,vector<int>vec){
 5         if(root==nullptr)
 6             return ;
 7         targetSum -= root->val;
 8         vec.push_back(root->val);
 9         if(root->left==nullptr&&root->right==nullptr&&targetSum == 0){
10             result.push_back(vec);
11             return ;
12         }
13         f(root->left,targetSum,vec);
14         f(root->right,targetSum,vec);
15     }
16     vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
17         vector<int> vec;
18         f(root,targetSum,vec);
19         return result;
20     }
21 };
View Code

 106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {//先后续遍历找根,再中序遍历划分,循环这个步骤找根划分。特征,左子树所有元素是连续的,右子树也是,中序遍历划分后得出长度,划分后续遍历
 2 public:
 3     TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
 4         if(inorder.size()==0||postorder.size()==0)
 5             return nullptr;
 6         TreeNode* root = new TreeNode(postorder[postorder.size()-1]);
 7         vector<int>leftInorder;
 8         vector<int>rightInorder;
 9         vector<int>leftPostorder;
10         vector<int>rightPostorder;
11         int i;
12         for(i=0;i<inorder.size()-1;i++){//左右要分开,因为后续遍历舍弃最后一个数字,中序遍历舍弃根节点数据
13             if(inorder[i]==root->val){
14                 break;
15             }
16             leftInorder.push_back(inorder[i]);
17         }
18          for(i++;i<inorder.size();i++){
19             rightInorder.push_back(inorder[i]);
20         }
21         int j;
22         for(j=0;j<postorder.size()-1;j++){
23             if(j<leftInorder.size())
24                 leftPostorder.push_back(postorder[j]);
25             else
26                 rightPostorder.push_back(postorder[j]);
27         }
28         root->left = buildTree(leftInorder,leftPostorder);
29         root->right = buildTree(rightInorder,rightPostorder);
30         return root;
31     }
32 };
View Code

 105. 从前序与中序遍历序列构造二叉树 - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {//先后续遍历找根,再中序遍历划分,循环这个步骤找根划分。特征,左子树所有元素是连续的,右子树也是,中序遍历划分后得出长度,划分后续遍历
 2 public:
 3     TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
 4         if(inorder.size()==0||preorder.size()==0)
 5             return nullptr;
 6         TreeNode* root = new TreeNode(preorder[0]);
 7         vector<int>leftInorder;
 8         vector<int>rightInorder;
 9         vector<int>leftPreorder;
10         vector<int>rightPreorder;
11         int i;
12         for(i=0;i<inorder.size()-1;i++){//左右要分开,因为后续遍历舍弃最后一个数字,中序遍历舍弃根节点数据
13             if(inorder[i]==root->val){
14                 break;
15             }
16             leftInorder.push_back(inorder[i]);
17         }
18          for(i++;i<inorder.size();i++){
19             rightInorder.push_back(inorder[i]);
20         }
21         int j;
22         for(j=1;j<preorder.size();j++){
23             if(j<=leftInorder.size())
24                 leftPreorder.push_back(preorder[j]);
25             else
26                 rightPreorder.push_back(preorder[j]);
27         }
28         root->left = buildTree(leftPreorder,leftInorder);
29         root->right = buildTree(rightPreorder,rightInorder);
30         return root;
31     }
32 };
View Code

 98. 验证二叉搜索树 - 力扣(LeetCode) (leetcode-cn.com)

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 8  *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 9  *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
10  * };
11  */
12 class Solution {//老想着一步到位,中序遍历存储上一次值,这样比较。不会。还是存储所有数据到数组再升序判断简单。还有等于妈的。。
13 public:
14     vector<int> res;
15     void f(TreeNode* root){
16         if(!root)
17             return ;
18         f(root->left);
19         res.push_back(root->val);
20         f(root->right);
21     }
22     bool isValidBST(TreeNode* root) {//中序遍历升序
23         f(root);
24         for(int i=0;i<res.size()-1;i++){
25             if(res[i]>=res[i+1])
26                 return false;
27         }
28         return true;
29     }
30 };
View Code

 530. 二叉搜索树的最小绝对差 - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {
 2 public:
 3     vector<int> res;
 4     void f(TreeNode* root){
 5         if(!root)
 6             return ;
 7         f(root->left);
 8         res.push_back(root->val);
 9         f(root->right);
10     }
11     int getMinimumDifference(TreeNode* root) {
12         f(root);
13         int minn = 1e5;
14         for(int i=0;i<res.size()-1;i++){
15             minn = min(minn,res[i+1]-res[i]);
16         }
17         return minn;
18     }
19 };
View Code

 501. 二叉搜索树中的众数 - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {
 2 public:
 3     unordered_map<int,int> map;
 4     void f(TreeNode* root){
 5         if(root==nullptr)
 6             return;
 7         map[root->val]++;
 8         f(root->left);
 9         f(root->right);
10 
11     }
12     bool static cmp(const pair<int,int>a,const pair<int,int>b){
13         return a.second>b.second;
14     }
15     vector<int> findMode(TreeNode* root) {
16         f(root);
17         vector<pair<int,int>>vec(map.begin(),map.end());
18         sort(vec.begin(),vec.end(),cmp);
19         vector<int>result;
20         result.push_back(vec[0].first);
21         for(int i=1;i<vec.size();i++){
22             if(vec[i].second==vec[0].second)
23                 result.push_back(vec[i].first);
24             else
25                 break;
26         }
27         return result;
28     }
29 };
View Code

236. 二叉树的最近公共祖先 - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {
 2 public:
 3     TreeNode* f(TreeNode* root, TreeNode* p, TreeNode* q){
 4         if(root==NULL){
 5             return root;
 6         }
 7         TreeNode* left = f(root->left,p,q);
 8         TreeNode* right = f(root->right,p,q);
 9         if(((left!=NULL)&&(right!=NULL))||((left!=NULL)&&(root==p||root==q))||((root==p||root==q)&&(right!=NULL))){
10             return root;
11         }
12         else if(left!=NULL)
13             root = left;
14         else if(right!=NULL)
15             root = right;
16         else if(root!=p&&root!=q)
17             root = NULL;
18         return root;
19     }
20     TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
21         return f(root,p,q);
22     }
23 };
View Code

 235. 二叉搜索树的最近公共祖先 - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {//二叉搜索树特殊性,左小右大
 2 public:
 3      TreeNode* f(TreeNode* root, TreeNode* p, TreeNode* q){
 4         if(root==NULL){
 5             return root;
 6         }
 7         if(root->val>q->val&&root->val>p->val)
 8             return f(root->left,p,q);
 9         if(root->val<p->val&&root->val<q->val)
10             return f(root->right,p,q);
11         return root;
12     }
13     TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
14         return f(root,p,q);
15     }
16 };
View Code

 701. 二叉搜索树中的插入操作 - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {
 2 public:
 3     TreeNode* f(TreeNode* root,int val){
 4         if(root==nullptr){
 5             root = new TreeNode(val);
 6             return root;
 7         }
 8         if(val<root->val)
 9             root->left = f(root->left,val);
10         if(val>root->val)
11             root->right = f(root->right,val);
12         return root;
13     }
14     TreeNode* insertIntoBST(TreeNode* root, int val) {
15         return f(root,val);
16     }
17 };
View Code

 450. 删除二叉搜索树中的节点 - 力扣(LeetCode) (leetcode-cn.com)

两个思路,一个是根节点保留,找到根节点升序遍历的下一位,赋值给根节点,递归删除根节点的下一位。

还有一个是删除根节点,根节点左子树,接到根节点升序遍历的下一位,的左子树。

 1 class Solution {
 2 public:
 3     TreeNode* deleteNode(TreeNode* root, int key) {//还是分类讨论思路,不要以不空操作,以空判断。
 4         if(root==nullptr)
 5             return root;
 6         if(root->val == key){
 7             if(!root->left&&!root->right)
 8                 return nullptr;
 9             else if(!root->left){//最终递归终止条件
10                root = root->right;
11             }else if(!root->right){
12                 root = root->left;
13             }else{//左右子树都不为空,最复杂,按照中序遍历升序,下面是按照后一位作为root
14                 TreeNode* temp = root->right;
15                 while(temp->left)
16                     temp = temp->left;
17                 root->val = temp->val;//赋值根节点后,要删除temp节点,temp节点左为空,右节点可能为空
18                 delete temp;
19             }
20             return root;
21         }
22         if(key<root->val)
23             root->left = deleteNode(root->left,key);
24         if(key>root->val)
25             root->right = deleteNode(root->right,key);
26         return root;
27     }
28 };
View Code

 669. 修剪二叉搜索树 - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {
 2 public:
 3     TreeNode* trimBST(TreeNode* root, int low, int high) {
 4         if(root==nullptr)
 5             return nullptr;
 6         if(root->val<low){
 7             root->right = trimBST(root->right,low,high);
 8             root = root->right;
 9         }else if(root->val>high){
10             root->left = trimBST(root->left,low,high);
11             root = root->left;
12         }else if(root->val<=high&&root->val>=low){
13             root->left = trimBST(root->left,low,high);
14             root->right = trimBST(root->right,low,high);
15         }
16         return root;
17     }
18 };
View Code

 108. 将有序数组转换为二叉搜索树 - 力扣(LeetCode) (leetcode-cn.com)

别人的简洁代码

 1 class Solution {
 2 public:
 3     TreeNode* dfs(vector<int>& nums,int p_left,int p_right)
 4     {
 5         if(p_left>=p_right)return NULL;
 6         int mid = (p_right+p_left)/2;
 7         TreeNode *root = new TreeNode(nums[mid]);
 8         root->left  = dfs(nums,p_left,mid);
 9         root->right = dfs(nums,mid+1,p_right);
10         return root;
11     }
12     TreeNode* sortedArrayToBST(vector<int>& nums) {
13         int len = nums.size();
14         return dfs(nums,0,len);
15     }
16 };
View Code

我的

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 8  *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 9  *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
10  * };
11  */
12 class Solution {
13 public:
14     TreeNode* f(TreeNode* root,vector<int> nums,int i,int end){//每次取中点作为根。
15         // cout<<i<<end<<endl;
16         if(i>end)
17             return root;
18         if(root == nullptr){
19             root = new TreeNode(nums[(i+end)/2]);
20             // cout<<"root->val="<<root->val<<endl;;
21             if(i!=end){//剪枝
22                 root->left = f(root->left,nums,i,(i+end)/2-1);
23                 root->right = f(root->right,nums,(i+end)/2+1,end);
24             }
25            // return root;//为啥子在这加一个return树才能构建,因为二次声明了root,出了bug
26         }
27         else if(nums[(i+end)/2]<root->val)//好像没必要。
28             root->left = f(root->left,nums,i,end);
29         else if(nums[(i+end)/2]>root->val)
30             root->right = f(root->right,nums,i,end);
31         return root;
32     }
33     TreeNode* sortedArrayToBST(vector<int>& nums) {
34         if(nums.size()==0)
35             return nullptr;
36         TreeNode* root = new TreeNode(nums[nums.size()/2]);
37         root->left = f(root->left,nums,0,nums.size()/2-1);
38         root->right = f(root->right,nums,nums.size()/2+1,nums.size()-1);
39         return root;
40     }
41 };
View Code

 

posted @ 2022-01-21 16:32  剩下的交给时间就好  阅读(12)  评论(0编辑  收藏  举报