路径专题
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;
}
}