java算法第十七天 | ● 513.找树左下角的值 ● 112. 路径总和 113.路径总和ii ● 106.从中序与后序遍历序列构造二叉树 105.从前序与中序遍历序列构造二叉树

513.找树左下角的值

leetcode链接
注意,这道题的左下角值一定位于最后一层,因此不能单纯地向左下遍历。
本题使用层序遍历更加易懂,也可以使用递归方法实现。
方法一、层序遍历

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int findBottomLeftValue(TreeNode root) {
        Deque<TreeNode> queue=new LinkedList<>();
        queue.add(root);
        int res=0;
        while(!queue.isEmpty()){
            int len=queue.size();
            res=queue.peek().val;
            while(len-->0){
                TreeNode temp=queue.poll();
                if(temp.left!=null) queue.add(temp.left);
                if(temp.right!=null) queue.add(temp.right);
            }
        }
        return res;

    }
}

方法二、递归

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    private int value=0;
    private int maxdepth=0;
    public int findBottomLeftValue(TreeNode root) {
        value=root.val;
        getValue(root,1);
        return value;
    }

    public void getValue(TreeNode node,int depth){
        if(node==null) return;
        if(node.left==null && node.right==null){
            if(depth>maxdepth){
                maxdepth=depth;
                value=node.val;
            }
        }
        if(node.left!=null) getValue(node.left,depth+1);
        if(node.right!=null) getValue(node.right,depth+1);
    }
}

112. 路径总和

leetcode链接
本题又一次设计要回溯的过程,而且回溯的过程隐藏的还挺深,建议先看视频来理解 .
代码随想录讲解
递归实现:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public boolean hasPathSum(TreeNode root, int targetSum) {
        if(root==null) return false;
        return getPath(root,targetSum);
    }
    public boolean getPath(TreeNode node,int count){
        if(node.left==null && node.right==null && count-node.val==0){
            return true;
        }
        if(node.left==null && node.right==null) return false;
        boolean left=false,right=false;
        if(node.left!=null){
           left=getPath(node.left,count-node.val); 
        }
        if(node.right!=null){
            right=getPath(node.right,count-node.val);
        }
        return (left || right);
    }
}

113.路径总和ii

leetcode链接
本题在上一题地基础上需要保存路径,只需要稍微更改一些操作。
代码实现

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
        List<Integer> path=new ArrayList<>();
        List<List<Integer>> res=new ArrayList<>();
        if(root==null) return res;
        getSum(root,targetSum,path,res);
        return res;


    }
    public void getSum(TreeNode node, int count,List<Integer> path,List<List<Integer>> res){
        path.add(node.val);
        if(node.left==null && node.right==null && count-node.val==0){
            res.add(new ArrayList<>(path));
            return;
        }
        if(node.left==null && node.right==null) return ;
        if(node.left!=null){
            getSum(node.left,count-node.val,path,res);
            path.remove(path.size()-1);//回溯
        }
        if(node.right!=null){
            getSum(node.right,count-node.val,path,res);
            path.remove(path.size()-1);//回溯
        }

    }
}

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

本题算是比较难的二叉树题目了,大家先看视频来理解
题目讲解

  • 第一步:如果数组大小为零的话,说明是空节点了。
  • 第二步:如果不为空,那么取后序数组最后一个元素作为节点元素。
  • 第三步:找到后序数组最后一个元素在中序数组的位置,作为切割点
  • 第四步:切割中序数组,切成中序左数组和中序右数组 (顺序别搞反了,一定是先切中序数组)
  • 第五步:切割后序数组,切成后序左数组和后序右数组
  • 第六步:递归处理左区间和右区间

一开始做的是不用HashMap索引中序遍历结果的方法,但这样的效率不高,代码比较好懂。主要要注意的是区间的开闭

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        if(inorder.length==0) return null;
        return getTree(inorder,0,inorder.length,postorder,0,postorder.length);

    }
    public TreeNode getTree(int[] inorder,int startI,int endI, int[] postorder,int startP,int endP){
        if(endP-startP<=0 || endI-startI<=0) return null;
        TreeNode root=new TreeNode(postorder[endP-1]);
        int i=startI;
        int num=0;
        while(inorder[i]!=root.val){
            i++;
            num++;
        }
        root.left=getTree(inorder,startI,i,postorder,startP,startP+num);
        root.right=getTree(inorder,i+1,endI,postorder,startP+num,endP-1);
        return root;
    }
}

使用Map优化的代码

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        if(inorder.length==0) return null;
        return getTree(inorder,0,inorder.length,postorder,0,postorder.length);

    }
    public TreeNode getTree(int[] inorder,int startI,int endI, int[] postorder,int startP,int endP){
        if(endP-startP<=0 || endI-startI<=0) return null;
        TreeNode root=new TreeNode(postorder[endP-1]);
        int i=startI;
        int num=0;
        while(inorder[i]!=root.val){
            i++;
            num++;
        }
        root.left=getTree(inorder,startI,i,postorder,startP,startP+num);
        root.right=getTree(inorder,i+1,endI,postorder,startP+num,endP-1);
        return root;
    }
}

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

与后序中序遍历的思想一样。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    Map<Integer,Integer> inorderMap=new HashMap<>();
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        for(int i=0;i<inorder.length;i++){
            inorderMap.put(inorder[i],i);
        }
        return getTree(preorder,0,preorder.length,inorder,0,inorder.length);

    }
    public TreeNode getTree(int[] preorder, int startP,int endP, int[] inorder,int startI,int endI){
        if(endI-startI<=0 || endP-startP<=0) return null;
        TreeNode root=new TreeNode(preorder[startP]);
        int indexI=inorderMap.get(root.val);
        int k=indexI-startI;
        root.left=getTree(preorder,startP+1,startP+1+k,inorder,startI,indexI);
        root.right=getTree(preorder,startP+1+k,endP,inorder,indexI+1,endI);
        return root;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值