代码随想录算法刷题训练营第十四天 | 513.找树左下角的值 112. 路径总和 106.从中序与后序遍历序列构造二叉树

 二叉树结点的深度是指当前结点到根节点的海拔;前序求深度

二叉树结点的高度是当前结点到最远叶子结点的海拔;后序求高度

 513.找树左下角的值

题目链接:. - 力扣(LeetCode)

文章讲解:代码随想录 (programmercarl.com)

 思路:最深一层的最左侧的那个结点

可以用层序遍历,遍历每一层时,保存第一个结点,最后就是最左结点啦.如何保存第一个呢

public int findBottomLeftValue(TreeNode root) {
    Queue<TreeNode> queue = new LinkedList<>();
    queue.offer(root);
    int num=0;
    while(!queue.isEmpty()) {
        int size = queue.size();
        int count = 1;
        for(int i=0;i<size;i++) {
            TreeNode node = queue.poll();
            if(node.left != null)queue.offer(node.left);
            if(node.right != null)queue.offer(node.right);
            if(i == 0) num = node.val;
            
        }
    }
    // findTarget(root,0);
    return num;
}

递归法:

求最大深度时的最左结点;用递归让最左边先被遍历,也是用一个depth和result来限定每层第一个结点

public void findTarget(TreeNode node,int depth) {
    if(node.left == null && node.right == null) {
        if(depth > maxDepth) {
            maxDepth = depth;
            result = node.val;
        }
        return;
    }//中
    if(node.left != null) {//左
        depth++;
        findTarget(node.left,depth);
        depth--;
    }
    if(node.right != null) {//右
        depth++;
        findTarget(node.right,depth);
        depth--;
    }
}

112. 路径总和

题目链接:. - 力扣(LeetCode)

文章讲解:代码随想录 (programmercarl.com)

思路:要看所有从根节点到叶结点的路径值和是否为目标值

递归: 这里递归函数的含义是看该节点下所有路径是否满足

  • 参数返回值:参数为结点和总和;返回值是boolean类型
  • 终止条件是当前结点为叶结点且总和与目标相等,返回true,如果只是叶结点,就返回false
  • 单层逻辑(推卸责任的过程):看该结点左右孩子下的路径是否满足
public boolean isEqual(TreeNode node,int targetSum,int sum) {
    sum += node.val;
    if(sum == targetSum && node.left == null && node.right == null)return true;
    if(node == null)return false;
    
    boolean left=false;
    boolean right=false;
    if(node.left != null) {
        left = isEqual(node.left,targetSum,sum);
    }
    if(node.right != null) {
        right = isEqual(node.right,targetSum,sum);
    }
    return (left || right);
}

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

题目链接:​​​​​​​. - 力扣(LeetCode)

文章讲解:代码随想录 (programmercarl.com)

 思路:思路就是模拟人工求解时的过程:

  1. 如果数组为空就返回空
  2. 取后序数组最后一个为根节点root
  3. 在中序数组中找到root位置idx
  4. 把中序数组分割为[0,x);[x+1,size)
  5. 后序数组去掉最后一个元素,跟中序一样分割为:[0,x);[x,size]
  6. 把责任推给左右孩子,让左左 右右继续这个过程

    public TreeNode build(List<Integer> inOrder,List<Integer> postOrder) {
        if(postOrder.size()==0)return null;
        int treenode = postOrder.get(postOrder.size()-1);
        TreeNode node = new TreeNode(treenode);

        if(postOrder.size() == 1) return node;

        int idx = 0;
        for(int i=0;i<inOrder.size();i++) {
            if(inOrder.get(i)==treenode){
                idx = i;
                break;
            }
        }
        //分割inOrder
        List<List<Integer>> list = partition(inOrder,idx,false);
        List<Integer> leftInOrder = list.get(0);
        List<Integer> rightInOrder = list.get(1);
        //去掉postOrder最后一个元素
        postOrder.remove(postOrder.size()-1);
        //分割postOrder
        list = partition(postOrder,idx,true);
        List<Integer> leftPostOrder = list.get(0);
        List<Integer> rightPostOrder = list.get(1);
        node.left = build(leftInOrder,leftPostOrder);
        node.right = build(rightInOrder,rightPostOrder);
        return node;
    }

开辟数组浪费时间,所以用下标来表示

public TreeNode build(int[] inOrder,int inOrderBegin,int inOrderEnd,int[] postOrder,int postOrderBegin,int postOrderEnd) {
    if(postOrderEnd == postOrderBegin)return null;
    int treenode = postOrder[postOrderEnd-1];
    TreeNode node = new TreeNode(treenode);

    if(postOrderEnd - postOrderBegin == 1) return node;

    int idx = 0;
    for(int i=inOrderBegin;i<inOrderEnd;i++) {
        if(inOrder[i]==treenode){
            idx = i;
            break;
        }
    }
    //分割inOrder,左闭右开
    int leftInOrderBegin = inOrderBegin;
    int leftInOrderEnd = idx;

    int rightInOrderBegin = idx+1;
    int rightInOrderEnd = inOrderEnd;
    //去掉postOrder最后一个元素
    postOrderEnd--;
    //分割postOrder
    int leftPostOrderBegin = postOrderBegin;
    int leftPostOrderEnd = postOrderBegin + idx - inOrderBegin;
    int rightPostOrderBegin = leftPostOrderEnd;
    int rightPostOrderEnd = postOrderEnd;

    node.left = build(inOrder,leftInOrderBegin,leftInOrderEnd,postOrder,leftPostOrderBegin,leftPostOrderEnd);
    node.right = build(inOrder,rightInOrderBegin,rightInOrderEnd,postOrder,rightPostOrderBegin,rightPostOrderEnd);
    return node;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值