和上一道回溯的题思路大致相同:
从前往后依次遍历,之后拼接的数字为当前数字cur
的之后的数字,直到list
的长度等于k
,将list
加入到ans
当中。
class Solution {
public List<List<Integer>> combine(int n, int k) {
List<List<Integer>> ans = new ArrayList<>();
backtrack(n, k, 1, ans, new ArrayList<>());
return ans;
}
public void backtrack(int n, int k, int cur, List<List<Integer>> ans, List<Integer> list) {
if (list.size() == k) ans.add(new ArrayList<>(list));
else {
for (int i = cur; i <= n; ++i) {
list.add(i);
backtrack(n, k, i + 1, ans, list);
list.remove(list.size() - 1);
}
}
}
}
特别注意:
if
和else
的区分,否则if
要及时return
- 回溯的时候新的
cur
值应该是i+1
而不是cur+1
ans.add(new ArrayList<>(list));
在Java中,对象赋值是传递引用的。这意味着当你将一个对象赋给另一个变量时,它们实陘指向同一个对象。所以,如果你简单地将list添加到ans中,实际上你只是将对list的引用添加到了ans中,而不是list的副本。这就意味着当你后续修改list时,ans中对应的组合也会被修改,因为它们共享相同的引用。