引發錯誤結果的程式碼:
class Solution {
List<List<Integer>> result = new ArrayList<>();
LinkedList<Integer> path = new LinkedList<>();
public List<List<Integer>> combine(int n, int k) {
backTracking(n, k, 1);
return result;
}
public void backTracking(int n, int k, int startIndex) {
if (path.size() == k) {
result.add(path);
return;
}
for (int i = startIndex; i <= n; i++) {
path.add(i);
backTracking(n, k, i + 1);
path.removeLast();
}
}
}
正確程式碼:
class Solution {
List<List<Integer>> result = new ArrayList<>();
LinkedList<Integer> path = new LinkedList<>();
public List<List<Integer>> combine(int n, int k) {
backTracking(n, k, 1);
return result;
}
public void backTracking(int n, int k, int startIndex) {
if (path.size() == k) {
result.add(new ArrayList<>(path));
return;
}
for (int i = startIndex; i <= n; i++) {
path.add(i);
backTracking(n, k, i + 1);
path.removeLast();
}
}
}
原因:
在這段程式碼中,result 是儲存最終結果的列表,path 是儲存當前組合的臨時列表。在回溯演算法中,當找到一個滿足條件的組合時,我們需要將當前的組合加入到最終結果 result 中。
由於 path 是一個 LinkedList,直接將 path 新增到 result 中會有一些問題。因為 path 最開始是一個空的 LinkedList,在回溯的過程中,不斷地向其新增元素,然後又不斷地移除末尾元素。所以如果直接將 path 新增到 result 中,後續的操作可能會修改 path 的內容,導致 result 中的組合也隨之改變。
為了解決這個問題,我們需要將 path 新增到 result 時,建立一個新的 ArrayList 物件,將 path 的元素複製到新的列表中,然後將這個新的列表新增到 result 中。這樣做的目的是確保 path 的內容不會隨後續操作改變。因為 ArrayList 是透過複製的方式建立的,所以即使 path 之後被修改,新增到 result 中的組合也不會受到影響。
因此,result.add(new ArrayList<>(path)); 的作用是將當前的組合(由 path 代表)新增到 result 中並儲存。