Leetcode中二叉树中的路径相关题目解析以及java实现
讲完了搜索问题,我们再来看看二叉树中的路径相关的问题,让我们先列出相关的题目
- [112] Path Sum:路径和(一)-是否存在二叉树路径和等于给定值(根节点到叶子节点)
- [113] Path Sum II:路径和(二)-二叉树中路径和等于给定值的所有路径(根节点到叶子节点)
- [437] Path Sum III:路径和(三)-二叉树中路径和等于给定值的所有路径(任意两个节点)
- [257] Binary Tree Paths:二叉树从根节点到叶子节点的所有路径
- [124] Binary Tree Maximum Path Sum:二叉树中任意两个节点之间路径和的最大值(二叉树的最大路径和)
Path sum
class solution{
public boolean hasPathSum(TreeNode root,int sum){
if(root == null) return false;
if(root.left == null && root.right == null && root.val == sum)return true;
return hasPathSum(root.left,sum-root.val) || hashPathSum(root.right,sum-root.val);
}
}
这一题太简单了,用简单的分治法递归就可以解决了,就不多说了
Path sum II
这一题相比起第一题来说就有一些难度, 不仅仅是需要返回是否有满足条件的布尔值,而是需要返回一个有着所有满足要求条件路径的数组,这种题我们一开始就会想到以DFS来解决,利用一个数组来保存当前的路径并且回溯,用一个全局数组来保存结果即可。
class solution{
List<List<Integer>> res;
public List<List<Integer>> pathSum(TreeNode root, int sum){
res = new ArrayList<>();
if(root == null) return res;
List<Integer> list = new ArrayList<>();
list.add(root.val);
helper(root,list,root.val,sum);
}
private void helper(TreeNode root,List<Integer> list, int sum, int target){
if(root == null) return;
if(root.left == null && root.right== null && sum == target){
res.add(new ArrayList<>(list);
return;
}
if(root.left != null){
list.add(root.left.val);
helper(root.left,list,sum+root.left.val,target);
list.remove(list.size()-1);
}
if(root.right != null){
list.add(root.right.val);
helper(root.right,result,list,sum+root.right.val,target);
list.remove(list.size()-1);
}
}
}
这就是一道非常标准的需要利用DFS来解决的题目。
Path Sum III
找到一共有多少条路径是满足当前的要求的,但是这个路径并不一定需要从根节点开始,但是必须从上往下计算,也一样是用分治法来解决这个问题,但是要多写一个函数,用来处理当前节点的,然后再用当前函数来处理当前节点的左右子节点。
class Solution {
public int pathSum(TreeNode root, int sum) {
if(root == null){
return 0;
}
return helper(root, sum) + pathSum(root.left, sum) + pathSum(root.right, sum);
}
private int helper(TreeNode root,int sum){
if(root == null){
return 0;
}
return(sum == root.val?1:0)+helper(root.left,sum-root.val)+helper(root.right,sum-root.val);
}
}
Binary Tree max Path sum
这一题就稍微有点难了,难就难在可以随意选择起点和终点,博主也是在网上看的各种大神的解题思路才勉强看懂,对于每一个节点来说,我们都要知道到底是其子节点的和比较打还是右节点的值比较大,对于每一个左右子节点的为负数的情况我们都直接设为0,因为我们不希望加入负数,然后我们有一个全局的值来作为返回值,不断的把当前的左右节点加上当前节点的值和全局返回值比较和更新,然后再函数内递归返回当前左子树或者右子树最大值加上当前节点的值,语言描述有一点难理解,我们看代码吧
class Solution {
private int maxSum = Integer.MIN_VALUE;
public int maxPathSum(TreeNode root) {
helper(root);
return maxSum;
}
private int helper(TreeNode root){
if (root == null){
return 0;
}
int leftSum = Math.max(helper(root.left),0);
int rightSum = Math.max(helper(root.right),0);
int totalSum = leftSum + rightSum + root.val;
if(totalSum > maxSum){
maxSum = totalSum;
}
return root.val + Math.max(leftSum,rightSum);
}
}
Binary Tree Paths
这一题比较简单,我们同样是用分治法来解决,题目要求我们用一个字符串的数组来保存根节点到所有叶子节点的路径,我们就用一个字符串来保存当前的路径,当当前节点是叶子节点的时候就直接将该字符串加入到数组当中即可。
class Solution {
public List<String> binaryTreePaths(TreeNode root) {
List<String> result = new ArrayList<String>();
if(root == null){
return result;
}
helper(root,String.valueOf(root.val),result);
return result;
}
private void helper(TreeNode root, String path, List<String>result){
if(root == null){
return;
}
if(root.left == null && root.right == null){
result.add(path);
return;
}
if(root.left != null){
helper(root.left,path+"->"+String.valueOf(root.left.val),result);
}
if(root.right != null){
helper(root.right,path+"->"+String.valueOf(root.right.val),result);
}
}
}
下一篇我们还会继续总结二叉树中路径相关的问题。