算法通关村第八关——轻松搞定二叉树路径专题

54 阅读3分钟

路径专题

1.二叉树的所有路径

对应leetcode257题:257. 二叉树的所有路径

解题思路:需要找到二叉树从根节点出发到叶子节点的所有路径,可以使用深度优先搜索的思想,而二叉树的深搜过程其实就是前序遍历过程;

深搜指的是,从起始位置出发一直走一直走,直到没路可走,才返回到前一个位置,找到一条新的路之后再继续按照这条路一直走,重复此过程,即可遍历图中所有节点;

而二叉树的前序遍历,从头节点开始,一直走到左子树的最左节点然后回到该最左节点上一个位置,判断在该位置是否存在右孩子,若存在,当前节点来到右孩子位置,再次判断当前节点是否存在左孩子,如果存在,继续一直向下找左孩子,直到为空,然后再返回查找右孩子;

代码如下:

public static List<String> binaryTreePaths(TreeNode root) {
    // 用于收集路径
    List<String> resList = new ArrayList<>();
    // 用于探索路径
    process(root, "", resList);
    // 返回集合
    return resList;
}

public static void process(TreeNode root, String path, List<String> resList) {
    // 如果当前节点为null,直接向上递归;
    if (root == null) {
        return;
    }
    // 当前路径拼接上root节点的值
    path = path + root.val;
    // 如果当前节点root的左右孩子都为null,说明其为叶子节点,将path添加到resList中
    if (root.left == null && root.right == null) {
        resList.add(path);
        return;
    }
    // 递归寻找左子树的全部路径
    process(root.left, path + "->", resList);
    // 递归寻找右子树的全部路径
    process(root.right, path + "->", resList);
}
2.路径总和

对应leetcode112题:112. 路径总和

这一题和上一题很类似,上一题要求全部路径,该题只需要判断有无指定的路径;

利用回溯来解决问题

如果当前位置来到叶子节点,但路径和curSum 不等于目标和 targetSum,此时就要向上返回,不过向上返回之前需要在curSum中减去当前节点的值;

对于下面过程,只需找到一条符合条件的路径之后,dfs方法返回的结果会一直为true;

 public boolean hasPathSum(TreeNode root, int targetSum) {
       return dfs(root,0,targetSum);
    }
    public static boolean dfs(TreeNode root,int curSum,int targetSum){
        // 如果当前位置为null,直接返回false,因为整条路径都遍历到null了,此时还是没有和目标路径匹配;
        if(root == null){
           return false;
        }
        // 当前这条路径和加上root节点的值;
        curSum+=root.val;
        // 如果当前节点为叶子节点,同时当前路径和等于目标路径和,返回true即可;
        if(root.left ==null && root.right == null && curSum == targetSum){
            return true;
        }
        // 一直向下遍历左子树
        boolean left=dfs(root.left,curSum,targetSum);    
        // 一直向下遍历右子树
        boolean right=dfs(root.right,curSum,targetSum);
        // 如果当前节点的左子树和右子树没有找到符合条件的路径,就减去当前节点的值,表示目标和路径中不会包含当前节点的值;
        //返回false即可;否则返回true;
        if(!left && !right){
            curSum-=root.val;
            return false;
        }else{
            return true;
        }
    }