记录一个小问题

引发错误结果的代码:

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 中并保存。

posted @ 2024-04-25 11:21  AI未来10Y  阅读(2)  评论(0编辑  收藏  举报