代码随想录Day21

513.找树左下角的值

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

思路:层序遍历,找到最后一层,然后弹出第一个值,怎么确定是最后一层?用ArrayList存,存完先求size,再get(size - 1)

层序遍历(AC)
class Solution {
    public int findBottomLeftValue(TreeNode root) {
        List<List<Integer>> res = new ArrayList<>();
        Queue<TreeNode> que = new LinkedList<>();
        que.offer(root);
        while(!que.isEmpty()){
            List<Integer> list = new ArrayList<>();
            int size = que.size();
            while(size>0){
                TreeNode temp = que.poll();
                list.add(temp.val);
                if(temp.left!=null) que.offer(temp.left);
                if(temp.right!=null) que.offer(temp.right);
                size--;
            }
            res.add(list);
        }
        int len = res.size();
        List<Integer> result = res.get(len - 1);
        return result.get(0);
    }
}
答案
迭代法
//迭代法
class Solution {
    public int findBottomLeftValue(TreeNode root) {
        Queue<TreeNode> que = new LinkedList<>();
        que.offer(root);
        int res = 0;
        while(!que.isEmpty()){
            int size = que.size();
            for(int i = 0; i < size; i++){
                TreeNode temp = que.poll();
                if(i == 0) res = temp.val;
                if(temp.left!=null) que.offer(temp.left);
                if(temp.right!=null) que.offer(temp.right);
            }
        }
        return res;
    }
}
 递归法
class Solution {
    private int maxDeep= -1;
    private int value = 0;
    public int findBottomLeftValue(TreeNode root) {
        value = root.val;
        findLeftValue(root,0);
        return value;
    }

    private void findLeftValue (TreeNode root,int deep) {
        if (root == null) return;
        if (root.left == null && root.right == null) {
            if (deep > maxDeep) {
                value = root.val;
                maxDeep= deep;
            }
        }
        if (root.left != null) findLeftValue(root.left,deep + 1);
        if (root.right != null) findLeftValue(root.right,deep + 1);
    }
}
小结

🍉层序遍历的关键是队列!——我的思路是,遍历后的内容都存起来,全部遍历完再取出。卡尔的迭代法,直接用一个队列,找队列里的第一个,因为队列空的时候就是在最后一行。

🍉递归的关键深度和隐藏的回溯,下面两个代码效果是一样的

if (root.left != null) findLeftValue(root.left,deep + 1);

if (root.left != null) {
    deep++;
    findLeftValue(root.left,deep);
    deep--;
}

🍉递归三步曲

1、参数:当前节点,深度;返回值:void

2、终止条件:遇到叶子节点,就对比当前深度与最大深度,更新叶子节点

3、处理逻辑: 控制回溯,注意要先左后右,因为这样遍历到最深一层的左节点之后,res就不会再更新了,也就保证了res是左下角的值

112.路径总和

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

思路:印象中是用递归+回溯

递归三步曲

1、参数:当前节点,当前路径和,返回值,void

2、终止条件:叶子节点,判断下和是否等于目标值,等于就更新标志位,不等于就返回-1;

3、单层逻辑:

尝试
class Solution {
    public boolean hasPathSum(TreeNode root, int targetSum) {
        int sum = 0;
        return getSum(root,sum) == -1 ? true : false;
    }
    public int getSum(TreeNode root,int sum){
        sum+=root.val;
        if(root.left==null && root.right == null){
            return sum == targetSum ? -1:0;
        }
        if(root.left!=null) return getSum(root.left,sum);
        if(root.right!=null) return getSum(root.right,sum);
    } 
}
答案
class Solution {
    public boolean hasPathSum(TreeNode root, int targetSum) {
        if (root == null) return false; // 为空退出

        // 叶子节点判断是否符合
        if (root.left == null && root.right == null) return root.val == targetSum;

        // 求两侧分支的路径和
        return hasPathSum(root.left, targetSum - root.val) || hasPathSum(root.right, targetSum - root.val);
    }
}
小结

🍉我的思路是,路径求和之后再跟目标值比较,卡尔的思路是目标值在路径上不断减少,找到叶子节点,就判断是否为跟目标值累减之后的值相等

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

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

思路:没有思路,不要说给出我这些信息了,再多给我一个前序遍历序列,我也不知道怎么构造二叉树,按理说,反向构造二叉树,一个序列不就够了吗,关键就是root、left、right每个节点的关系要搞对,

练习
class Solution {
    private Map<Integer,Integer> map;
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        map = new HashMap<>();
        for(int i = 0; i < inorder.size(); i++){
            map.put(inorder[i],i);
        }
        int root = postorder[postorder.size()-1];
        int rootIndex = map.get(root);
        return findNode(inorder,0,inorder.length,postorder,0,postorder.length);

    }
    public TreeNode findNode(int[] inorder,int inStart,int inEnd, int[] postorder,int postStart,int postEnd){
        int lenOfLeft = 
    }
}
答案
class Solution {
    Map<Integer, Integer> map;  // 方便根据数值查找位置
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        map = new HashMap<>();
        for (int i = 0; i < inorder.length; i++) { // 用map保存中序序列的数值对应位置
            map.put(inorder[i], i);
        }

        return findNode(inorder,  0, inorder.length, postorder,0, postorder.length);  // 前闭后开
    }

    public TreeNode findNode(int[] inorder, int inBegin, int inEnd, int[] postorder, int postBegin, int postEnd) {
        // 参数里的范围都是前闭后开
        if (inBegin >= inEnd || postBegin >= postEnd) {  // 不满足左闭右开,说明没有元素,返回空树
            return null;
        }
        int rootIndex = map.get(postorder[postEnd - 1]);  // 找到后序遍历的最后一个元素在中序遍历中的位置
        TreeNode root = new TreeNode(inorder[rootIndex]);  // 构造结点
        int lenOfLeft = rootIndex - inBegin;  // 保存中序左子树个数,用来确定后序数列的个数
        root.left = findNode(inorder, inBegin, rootIndex,
                            postorder, postBegin, postBegin + lenOfLeft);
        root.right = findNode(inorder, rootIndex + 1, inEnd,
                            postorder, postBegin + lenOfLeft, postEnd - 1);

        return root;
    }
}
小结

🍉之所以要中序,后序两个序列,是因为只有后序的话,仅仅是【左右中】无法确定分割位置,加上一个中序【左中右】就能够分开左右

🍉前序+中序,后序+中序,可以构造唯一的二叉树,前序+后序不行,无法确定分割点

🍉先把中序数组存进map里面,方面取出根节点的下标,构造节点

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值