leetcode[Path Sum III]//待整理多种解法
2017-07-21 11:38
441 查看
错误解法(题目要求只需要从上到下的某一段,而不是从根节点开始,这个错误解法求的是从根节点到下面结点的距离,不符合题意,用先根遍历求和不如下面解法一的DFS来得简单,因为DFS每次弹栈,压栈的形式固定,而先根遍历需要连续压栈什么的,无法保证Stack<TreeNode>与Stack<Integer>的同步压栈与弹栈,这里先根遍历还有问题,下面解法一的DFS是正确的):
错误解法二(这种取出所有的路径的方式会多计数,因为多条路径可能有交叉部分,而满足条件的某一段刚好就是交叉部分,所以不对):
解法一:
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ public class Solution { public int pathSum(TreeNode root, int sum) { int count = 0; Stack<Integer> stackInt = new Stack<>();//用一个Stack记录下根节点到每个节点的距离之和 Stack<TreeNode> stackTree = new Stack<>(); //采用深度优先遍历 if(root == null) return 0; stackTree.push(root); //System.out.println(root.val); stackInt.push(root.val); if(root.val == sum)//计数 count++; TreeNode temp = root.left; while(temp != null){//先压入左最左边那一路 stackTree.push(temp); //System.out.println(temp.val); int pop = stackInt.pop(); stackInt.push(temp.val + pop);//根节点到当前节点的值与其父结点有关 if((temp.val + pop) == sum)//计数 count++; temp = temp.left; } while(!stackTree.isEmpty()){ temp = stackTree.pop(); temp = temp.right; while(temp != null){ stackTree.push(temp); //System.out.println(temp.val); int pop = stackInt.pop(); stackInt.push(temp.val + pop);//根节点到当前节点的值与其父结点有关 if((temp.val + pop) == sum)//计数 count++; temp = temp.left; } } return count; } }
错误解法二(这种取出所有的路径的方式会多计数,因为多条路径可能有交叉部分,而满足条件的某一段刚好就是交叉部分,所以不对):
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ public class Solution { public int pathSum(TreeNode root, int sum) { int count = 0; //采用深度优先遍历,求出根节点到每一个叶节点的完整路径,再来筛选每一条路径中存在的段数 Stack<TreeNode> stackTree = new Stack<>(); Stack<ArrayList<Integer>> stackList = new Stack<>();//用于保存由根节点到每个结点的具体路径,因为弹栈后右子节点会丢失父结点的信息 ArrayList<ArrayList<Integer>> list = new ArrayList<>();//用于保存所有的路径 ArrayList<Integer> tempList = new ArrayList<>();//用于保存每条路径 if(root == null) return 0; stackTree.push(root); //System.out.println(root.val); tempList.add(root.val);//在应该遍历打印的位置插入节点 stackList.push(new ArrayList<>(tempList));//需要新建,因为之后tempList会被修改 TreeNode temp = root.left; while(temp != null){//先压入左最左边那一路 stackTree.push(temp); //System.out.println(temp.val); //需要新建,因为之后tempList会被修改 tempList = new ArrayList<>(stackList.peek());//通过父结点的list再插入,这里父结点没有弹出,就不弹栈 tempList.add(temp.val);//在应该遍历打印的位置插入节点 stackList.push(tempList); if(temp.left == null && temp.right == null){//判断是否是叶节点 list.add(tempList);//如果是叶节点,则这条路径完结 } temp = temp.left; } while(!stackTree.isEmpty()){ temp = stackTree.pop(); //需要新建,因为之后tempList会被修改 tempList = new ArrayList<>(stackList.pop());//通过父结点的list再插入,这里父结点弹出,需要弹栈 temp = temp.right; while(temp != null){ stackTree.push(temp); //System.out.println(temp.val); tempList.add(temp.val);//在应该遍历打印的位置插入节点 stackList.push(tempList); if(temp.left == null && temp.right == null){//判断是否是叶节点 list.add(tempList);//如果是叶节点,则这条路径完结 } temp = temp.left; } } //开始从所有路径中查找满足条件的段数 for(int i = 0; i < list.size(); i++){ tempList = list.get(i); System.out.println(Arrays.asList(tempList).toString()); //打印每一条路径 for(int j = 0; j < tempList.size(); j++){//用两层循环来找段落数,因为可能出现在中间某一段 int tempSum = 0;//每一次中间某段要清零,因为实际求和是在最内层循环 for(int k = j; k < tempList.size(); k++){ tempSum += tempList.get(k); System.out.println(tempSum); if(tempSum == sum) count++; } } } return count; } }
解法一:
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ public class Solution { /*错误解法(题目要求只需要从上到下的某一段,而不是从根节点开始,这个错误解法求的是从根节点到下面结点的距离,不符合题意):*/ //这里改进错误解法一,采用嵌套的遍历,在遍历到一个结点时,将其视为根节点进行遍历即可 public int pathSum(TreeNode root, int sum) {//外层遍历 int count = 0; Stack<TreeNode> stackTree = new Stack<>(); //采用深度优先遍历 if(root == null) return 0; stackTree.push(root); //System.out.println(root.val); count += pathSumHelp(root, sum); TreeNode temp = root.left; while(temp != null){//先压入左最左边那一路 stackTree.push(temp); //System.out.println(temp.val); count += pathSumHelp(temp, sum); temp = temp.left; } while(!stackTree.isEmpty()){ temp = stackTree.pop(); temp = temp.right; while(temp != null){ stackTree.push(temp); //System.out.println(temp.val); count += pathSumHelp(temp, sum); temp = temp.left; } } return count; } private int pathSumHelp(TreeNode root, int sum){//内层遍历,这里弹出的结点不再参与,所以不会有错误解法二那种交叉重复的问题 int count = 0; Stack<TreeNode> stackTree = new Stack<>(); Stack<Integer> stackInt = new Stack<>(); if(root == null) return 0; stackTree.push(root); stackInt.push(root.val);//直接在插入结点时就计算出根节点到该结点的距离,再判断一下 if(root.val == sum) count++; //进行DFS遍历 while(!stackTree.isEmpty()){ TreeNode tempTree = stackTree.pop(); int pop = stackInt.pop(); //压入左结点 if(tempTree.left != null){ stackTree.push(tempTree.left); stackInt.push(tempTree.left.val + pop); if((tempTree.left.val + pop) == sum) count++; } //压入右结点 if(tempTree.right != null){ stackTree.push(tempTree.right); stackInt.push(tempTree.right.val + pop); if((tempTree.right.val + pop) == sum) count++; } } return count; } }
相关文章推荐
- leetcode[Sum of Left Leaves]//待整理多种解法
- leetcode[Range Sum Query - Immutable]//待整理多种解法
- leetcode[Minimum Index Sum of Two Lists]//待整理多种解法
- leetcode[Two Sum IV - Input is a BST]//待整理多种解法
- leetcode[Reverse Words in a String III]//待整理多种解法
- leetcode [Rotate Array]//待整理多种解法
- Leetcode 437. Path Sum III
- leetcode [Remove Linked List Elements]//待整理多种解法
- leetcode[Reshape the Matrix]//待整理多种解法
- leetcode [Implement Stack using Queues]//待整理多种解法
- LeetCode-Path Sum III
- LeetCode--437. Path Sum III(路径和)Python
- leetcode[Detect Capital]//待整理多种解法
- leetcode[Convert a Number to Hexadecimal]//待整理多种解法
- leetcode[Add Strings]//待整理多种解法
- leetcode[Subtree of Another Tree]//待整理多种解法
- LeetCode - 437. Path sum III
- 【LeetCode】112,113,437. Path Sum I, II, III
- leetcode[Longest Palindromic Substring]//待整理多种解法
- Leetcode-437. Path Sum III