例如以下关于DFS的两个问题是二叉树,为什么第一个需要回溯跟踪(每次命中叶节点时都删除工作集中的最后一个元素),另一个不是?他们都要求所有的路径都满足要求,而不是试图找出路径是否存在,因为路径已经到达了一个叶子的末端,为了格式化其他可能的路径,我们不应该回溯到我们访问的最后一个节点?
https://leetcode.com/problems/path-sum-ii/
https://leetcode.com/problems/binary-tree-paths/
回答第一个问题:
public List<List<Integer>> pathSum(TreeNode root, int sum) {
List<List<Integer>> finalResult=new ArrayList<List<Integer>>();
List<Integer> tempResult = new ArrayList<Integer>();
pathSumHelper(root,sum,tempResult,finalResult);
return finalResult;
}
public void pathSumHelper(TreeNode node, int sum, List <Integer> tempResult, List<List<Integer>> finalResult){
if(node == null) return;
sum -= node.val;
if( node.left == null && node.right == null ){
if( sum == 0){
tempResult.add(node.val);
finalResult.add(new ArrayList<Integer>(tempResult));
tempResult.remove(tempResult.size() -1);
}
return;
}
tempResult.add(node.val);
pathSumHelper(node.left, sum, tempResult, finalResult);
pathSumHelper(node.right, sum, tempResult, finalResult);
tempResult.remove(tempResult.size() -1 );
}
回答第二个问题:
public List<String> binaryTreePaths(TreeNode root) {
List<String> finalResult = new ArrayList<String>();
String tempResult = "";
findPath(root, tempResult, finalResult);
return finalResult;
}
public void findPath(TreeNode node, String tempResult, List<String> finalResult){
if( node == null ){
return;
}
if(node.left == null && node.right == null){
tempResult += String.valueOf(node.val);
finalResult.add(tempResult);
// why no delete last integer added in tempResult before return?
return;
}
tempResult += String.valueOf(node.val);
findPath(node.left, tempResult+"->", finalResult);
findPath(node.right, tempResult+"->", finalResult);
// same, why no delete last integer added in tempResult before return?
}
答案 0 :(得分:1)
在第二种算法中,当您对mysql> select * from t1 order by A DESC, C DESC, D ASC;
+------+------+------+------------+
| A | B | C | D |
+------+------+------+------------+
| 1 | 1 | 4 | 2016-01-04 |
| 1 | 0 | 4 | 2016-01-07 |
| 1 | 1 | 3 | 2016-01-03 |
| 1 | 1 | 3 | 2016-01-06 |
| 1 | 1 | 2 | 2016-01-02 |
| 1 | 1 | 2 | 2016-01-05 |
| 1 | 0 | 2 | 2016-01-09 |
| 1 | 1 | 1 | 2016-01-01 |
| 1 | 1 | 1 | 2016-01-04 |
| 1 | 0 | 1 | 2016-01-08 |
+------+------+------+------------+
10 rows in set (0.00 sec)
-- query wanted
mysql> select t1.*
-> from t1 CROSS JOIN (select @even := 0, @odd := 0) param
-> order by
-> A DESC,
-> IF(B = 1, 2*(@odd := @odd + 1), 2*(@even := @even + 1) + 1),
-> C DESC,
-> D ASC;
+------+------+------+------------+
| A | B | C | D |
+------+------+------+------------+
| 1 | 1 | 1 | 2016-01-01 |
| 1 | 0 | 4 | 2016-01-07 |
| 1 | 1 | 2 | 2016-01-02 |
| 1 | 0 | 1 | 2016-01-08 |
| 1 | 1 | 3 | 2016-01-03 |
| 1 | 0 | 2 | 2016-01-09 |
| 1 | 1 | 4 | 2016-01-04 |
| 1 | 1 | 1 | 2016-01-04 |
| 1 | 1 | 2 | 2016-01-05 |
| 1 | 1 | 3 | 2016-01-06 |
+------+------+------+------------+
10 rows in set (0.00 sec)
进行递归调用时,您正在使用+运算符,同时传递findPath
+&#34; - &gt;&#34;作为一个论点。 + 运算符会导致连接,从而创建新的tempResult
对象。基本上在每个递归级别,您将新的String
对象传递到较低级别,并将每个级别的String
变量放在较低级别的范围之外。
因此,您实际上无法访问上层递归的tempResult
对象,即使您回溯,它也只会更新传递给该递归级别的String
对象而不是属于上层的String
,从未偶然开始!这就是为什么在第二种解决方案中不需要回溯的原因,因此没有完成。