代码随想录训练营第十八天513.找树左下角的值112. 路径总和113. 路径总和ii106.从中序与后序遍历序列构造二叉树105.从前序与中序遍历序列构造二叉树

 513.找树左下角的值

题目链接 513. 找树左下角的值 - 力扣(LeetCode)

讲解链接 代码随想录 (programmercarl.com)

 首先还是递归三部曲,在选择参数这里每次都会犹豫,不过本题选择了直接定义全局变量,记录深度:

int result;
    
    int maxDepth=INT_MIN;

同时精巧地在最下面一层先检测左边节点,并将最深层的左侧值赋予,再一次检测到最深层的元素时,一定不是最左值,不再赋值,同时每次进入跳出递归时不忘更改depth值实现回溯。

if(depth>maxDepth){
                maxDepth=depth;
                result=root->val;
            }

 if(root->left){
            depth++;
            getDepth(root->left,depth);
            depth--;
        }
        if(root->right){
            depth++;
            getDepth(root->right,depth);
            depth--;
        }

 112. 路径总和

题目链接 112. 路径总和 - 力扣(LeetCode)

讲解链接 代码随想录 (programmercarl.com)

 本题最精髓的地方在于在确定路径存在时返回什么样的值告诉上一层,这也涉及到了讲解的内容

再来看返回值,递归函数什么时候需要返回值?什么时候不需要返回值?这里总结如下三点:

  • 如果需要搜索整棵二叉树且不用处理递归返回值,递归函数就不要返回值。(这种情况就是本文下半部分介绍的113.路径总和ii)
  • 如果需要搜索整棵二叉树且需要处理递归返回值,递归函数就需要返回值。 (这种情况我们在236. 二叉树的最近公共祖先 (opens new window)中介绍)
  • 如果要搜索其中一条符合条件的路径,那么递归一定需要返回值,因为遇到符合条件的路径了就要及时返回。(本题的情况)代码随想录 (programmercarl.com)

 并在单层递归中判断返回值:

if(search(root->left,count))return true;

 113. 路径总和ii

题目链接  113. 路径总和 II - 力扣(LeetCode)

讲解链接 代码随想录 (programmercarl.com)

 同样是含有回溯的二叉树递归,同时判断路径,不同的是这次加入了数组,即需要将路径塞入数组中,并返回数组,这与之前的一道返回数组字符串的题类似257. 二叉树的所有路径 - 力扣(LeetCode)

 每次判断的代码:

if(root->left){
            temp.push_back(root->left->val);
            count-=root->left->val;
            search(root->left,count);
            count+=root->left->val;
            temp.pop_back();

        }
        if(root->right){
            temp.push_back(root->right->val);
            count-=root->right->val;
            search(root->right,count);
            count+=root->right->val;
            temp.pop_back();
        }

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

题目链接 106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode)

讲解链接 代码随想录 (programmercarl.com)

 本题最关键的就是要考虑清楚其中的数学关系:即根据中序数组的头节点元素作为根节点元素,并在后序数组中寻找根节点的值,同时将后序数组在根结点处跟为两段,一半为树左侧元素,一半为树右侧元素,并将中序数组同样的分为左右两枝的片段(大小与后序左右两枝等同)这样就实现了每一层的分割操作,再实现递归即可。

oot->left=traversal(leftIn,leftPost);
        root->right=traversal(rightIn,rightPost);

 105.从前序与中序遍历序列构造二叉树

题目链接 106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode)

讲解链接 代码随想录 (programmercarl.com)

 与上一题同样的思路,但是答案用了数字表示数组分割的位置,而不是再对数组进行直接分割,但是我按照上一题的思路编写,却发生了错误:


class Solution {
public:
    TreeNode* traversal(vector<int>&preorder,vector<int>& inorder){
        int valueRoot=inorder[0];
        TreeNode* root=new TreeNode(inorder[0]);
        if(preorder.size()==1)return root;
        int index;

        for(index=0;index<preorder.size()-1;index++){
            if(preorder[index]==valueRoot)break;
        }

        vector<int>preLeft(preorder.begin(),preorder.begin()+index);
        vector<int>preright(preorder.begin()+index+1,preorder.end());

        vector<int>inleft(inorder.begin()+1,inorder.begin()+1+preLeft.size());
        vector<int>inright(inorder.begin()+1+preLeft.size(),inorder.end());

        root->left=traversal(preLeft,inleft);
        root->right=traversal(preright,inright);

        return root;

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

 具体错误是最后输出的结果有问题,不知道不同的写法为什么会出错,感觉可能是分片没做好。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值