代码随想录算法训练营第十八天

文章介绍了如何在二叉树中寻找最左侧的值、判断路径和、计算路径总和,以及利用中序和后序遍历序列构建二叉树的算法,涉及递归和深度优先搜索的方法。
摘要由CSDN通过智能技术生成

今天一定要赶上进度,加油。

 找树左下角的值

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    int result = 0;
    void findleft(TreeNode * node,int depth){
        if(!node->left && !node->right){
            if(depth > maxDepth){
                result = node->val;
                maxDepth = depth;//保证是最左边的前提
            }
            return;
        }
        if(node->left){
            depth++;
            findleft(node->left,depth);
            depth--;
        }
        if(node->right){
            depth++;
            findleft(node->right,depth);
            depth--;            
        }
        return;
    }
    int findBottomLeftValue(TreeNode* root) {
        findleft(root,0);
        return result;
    }
private:
    int maxDepth = INT_MIN;
};

路径总和

112题:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    bool judge(TreeNode * node,int targetSum){
        if(!node->left && !node->right && targetSum == 0)return true;//因为在这里就做判断了,所以已经是减过的
        if(!node->left && !node->right)return false;//到子节点但是值不是0,那就返回。
        if(node->left){
            targetSum -=node->left->val;//解释同15行,需要减目标值,而不是中间值
            if(judge(node->left,targetSum))return true;
            targetSum +=node->left->val; 
        }
        if(node->right){
            targetSum -=node->right->val;
            if(judge(node->right,targetSum))return true;
            targetSum +=node->right->val;             
        }
        return false;
    }

    bool hasPathSum(TreeNode* root, int targetSum) {
        if(root == nullptr)return false;
        return judge(root,targetSum - root->val);
    }
};

113题:

这题首先因为需要遍历,所以不需要返回true or false,其次,标准答案的函数里把path放在了最外层,不需要让path进循环里(结果是一样的,操作上来看应该也是一样的)

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    vector<vector<int>> result;
    void traversal(TreeNode* node,int count,vector<int>path){
        if(!node->left && !node->right && count == 0){
            result.push_back(path);
            return;
        }
        if(!node->left && !node->right)return;
        if(node->left){
            count-= node->left->val;
            path.push_back(node->left->val);
            traversal(node->left,count,path);
            count+= node->left->val;
            path.pop_back();
        }
        if(node->right){
            count-= node->right->val;
            path.push_back(node->right->val);
            traversal(node->right,count,path);
            count+= node->right->val;
            path.pop_back();
        }
        return;
    }
    vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
        vector<int>True_path;
        result.clear();
        if(root == nullptr)return result;
        True_path.push_back(root->val);
        traversal(root,targetSum - root->val,True_path);
        return result;
    }
};

从中序与后序遍历序列构造二叉树

思路就是后序遍历的最后一个元素实际上是root,然后用root在中序做切割点。

然后左 右分开验证

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* traversal(vector<int>& inorder,vector<int>& postorder,int InBeginNum,int InEndNum,int PosBeginNum,int PosEndNum){
        if(PosEndNum == PosBeginNum)return nullptr;
        int rootvalue = postorder[PosEndNum - 1];\\这里卡很久,要记着用Num而不是.size()
        TreeNode* root = new TreeNode(rootvalue);
        if(PosEndNum - PosBeginNum == 1)return root;//这步其实在做最后的分割
        int qiegedianNum;
        for(qiegedianNum = InBeginNum;qiegedianNum<InEndNum;qiegedianNum++){
            if(rootvalue == inorder[qiegedianNum])break;
        }

        //中序切割
        int leftInBeginNum  = InBeginNum;
        int leftInEndNum    = qiegedianNum;
        int rightInBeginNum = qiegedianNum+1;
        int rightInEndNum   = InEndNum;
        //后序切割
        int leftPosBeginNum = PosBeginNum;
        int leftPosEndNum   = PosBeginNum + (qiegedianNum - InBeginNum);
        int rightPosBeginNum= PosBeginNum + (qiegedianNum - InBeginNum);
        int rightPosEndNum  = PosEndNum - 1;//最后一个节点是root
        // /* test */
        //         cout << "----------" << endl;
        // cout << "leftInorder :";
        // for (int i = leftInorderBegin; i < leftInorderEnd; i++) {
        //     cout << inorder[i] << " ";
        // }
        // cout << endl;

        // cout << "rightInorder :";
        // for (int i = rightInorderBegin; i < rightInorderEnd; i++) {
        //     cout << inorder[i] << " ";
        // }
        // cout << endl;

        // cout << "leftpostorder :";
        // for (int i = leftPostorderBegin; i < leftPostorderEnd; i++) {
        //     cout << postorder[i] << " ";
        // }
        // cout << endl;

        // cout << "rightpostorder :";
        // for (int i = rightPostorderBegin; i < rightPostorderEnd; i++) {
        //     cout << postorder[i] << " ";
        // }
        // cout << endl;
        // /*end*/


        root->left = traversal(inorder,postorder,leftInBeginNum,leftInEndNum,leftPosBeginNum,leftPosEndNum);
        root->right = traversal(inorder,postorder,rightInBeginNum,rightInEndNum,rightPosBeginNum,rightPosEndNum);
        return root;
    }

    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
         if (inorder.size() == 0 || postorder.size() == 0) return NULL;
        return traversal(inorder,postorder,0,inorder.size(),0,postorder.size());
    }
};

105题和106题基本一致,可以默写一遍试试看,这次用vector,不用脚标节省空间了。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
    TreeNode* traversal(vector<int>&preorder,vector<int>&inorder){
        if(preorder.size() == 0)return nullptr;
        TreeNode *root = new TreeNode(preorder[0]);
        if(preorder.size() == 1)return root;
        int qiegedian;
        for(qiegedian = 0;qiegedian < inorder.size();qiegedian++){
            if(inorder[qiegedian] == root->val)break;
        }
        vector<int>Leftpreorder(preorder.begin()+1,preorder.begin()+qiegedian+1);
        vector<int>Rightpreorder(preorder.begin()+qiegedian+1,preorder.end());//左闭右开牛逼。
        vector<int>Leftinorder(inorder.begin(),inorder.begin()+qiegedian);
        vector<int>Rightinorder(inorder.begin()+qiegedian+1,inorder.end());
        
        root->left = traversal(Leftpreorder,Leftinorder);
        root->right = traversal(Rightpreorder,Rightinorder);
        return root;
    }
public:
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        return traversal(preorder,inorder);
    }
};

这种还是看着简单点,就是新建的东西多。上半场游戏结束。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值