算法学习day05

一、二叉树的所有路径(递归(回溯))

整体思路:对二叉树进行前序递归遍历。(中左右,先输出,然后递归左子节点和右子节点);

1.确定递归函数的返回值为void 参数为TreeNode node,List<Integer> paths(单条路径),List<String> lists(路径的集合)

2.递归函数的终止条件:(root.left==null&&root.right==null)return ;

3.处理递归逻辑:

3.1 当遇到左节点不空

if(node.left!=null){
    traversal(node.left,lists,paths);
    paths.remove(paths.size()-1);
}

左节点不为空就继续向下递归,但是还要加回溯。

1->2->5 在5的左右子节点都为空的时候,然后把路径添加到lists中。然后回到函数中就要回到1->2,在2这个结点中,就要回到1。

3.2、遇到右结点为空 相同的逻辑

3.3  当左右节点都为空的时候,说明到了叶子节点。向下已经没有路了。在这种情况下要把paths单条路径中的结点都输出,并且使用StringBuilder拼接->;

代码:

  public List<String> binaryTreePaths(TreeNode root) {
        List<String> list = new ArrayList<>();
        if (root == null)
            return list;
        List<Integer> paths = new ArrayList<>();
        traversal(root, list, paths);
        return list;
    }

    public void traversal(TreeNode node, List<String> lists, List<Integer> paths) {
        // 前序遍历 中(将结点的值添加到paths中)
        paths.add(node.val);
        // 前序遍历 左
        if (node.left != null) {
            traversal(node.left, lists, paths);
            paths.remove(paths.size() - 1);
        }
        //前序遍历 右
        if (node.right != null) {
            traversal(node.right, lists, paths);
            paths.remove(paths.size() - 1);
        }
        // 如果遇到子节点,就把路径直接输出
        if (node.left == null && node.right == null) {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < paths.size() - 1; i++) {
                sb.append(paths.get(i)).append("->");
            }
            sb.append(paths.get(paths.size() - 1));
            lists.add(sb.toString());
            return;
        }
    }

二、左叶子之和(递归法)

1.返回值 :int  参数:TreeNode node

2.终止条件 (node==null) (node.left==null&&node.right==null) return 0;

3.递归逻辑:后序遍历(左右中)

左:递归左子树,得到左子树中左叶子结点的值

右:递归右子树,得到右子树中左叶子节点的值

中:合二为一

在进行左递归的时候,如果遇到左子树!=null 并且它是一个叶子节点。那么直接leftNum=node.val

代码:

public int sumOfLeftLeaves(TreeNode root) {
        return getSum(root);
    }

    public int getSum(TreeNode root) {
        if (root == null)
            return 0;// 如果结点为空
        if (root.left == null && root.right == null)
            return 0;// 如果是叶子节点 但不一定是左
            
        int leftSum=0;   
        
        //如果左边是一个左子节点 那么就进if条件 如果不是那么继续递归
        if(root.left!=null&&root.left.left==null&&root.left.right==null){
            leftSum=root.left.val;
        }else{
            leftSum=getSum(root.left);
        }

        int rightSum = getSum(root.right);// 右边的和
        return leftSum + rightSum;
    }

三、找树左下角的值(层序遍历/递归法)

层序遍历:

找到最后一层元素,然后返回第一个就可以。用这个很容易做出来。

List<List<Integer>> lists=new ArrayList<>();
Queue<TreeNode> queue=new ArrayDeque<>();
if(root!=null)queue.add(root);
while(!queue.isEmpty()){

    List<Integer> list=new ArrayList<>();
    int size=queue.size();
    while(size-->0){

          TreeNode node=queue.poll();
          list.add(node.val);
          if(node.left!=null)queue.add(node.left);
          if(node.right!=null)queue.add(node.right);
    }
    lists.add(list);
}
return lists.get(lists.size()-1).get(0);
递归法:

1.递归函数的返回值:void 参数:TreeNode node int depth;现在的深度(当前的深度与全局变量中的max_depth做对比,如果更大就更新)

2.递归函数的终止条件:当递归到叶子结点的时候if(node.left==null&&node.right==null)

处理逻辑:  if(depth>max_depth)max_depth=depth,result=node.val;(全局变量中也要定义一个result,作为返回的结果)

3.递归逻辑:

3.1.如果遇到叶子节点,那么就更新最大值。

3.2.如果结点不是叶子节点,那就继续向下遍历,先左后右。if(root.left!=null)depth++,traversal(root.left,depth),depth-- 要做回溯操作。

3.3.向右遍历 if(root.right!=null)depth++,traversal(root.right,depth),depth--

代码:

class Solution {
    int max_depth=Integer.MIN_VALUE;
    int result;
    public int findBottomLeftValue(TreeNode root) {
        traversal(root,0);
        return result;
    }
    public void traversal(TreeNode root,int depth){
        //终止条件 如果是一个叶子结点 那么就更新
        if(root.left==null&&root.right==null){
            if(depth>max_depth){
                max_depth=depth;
                result=root.val;
            }
        }
        if(root.left!=null){
            depth++;
            traversal(root.left,depth);
            //回溯
            depth--;
        }
        if(root.right!=null){
            depth++;
            traversal(root.right,depth);
            depth--;
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值