Я нашел решение ЗДЕСЬ. Может кто-нибудь объяснить, как это работает. В частности, одна из вещей, которую я не могу понять, - это рекурсивный вызов. В одном из них передается new ArrayList<>(path), в другом - просто path. Почему ? Между тем решение работает нормально.

public class Main {

    public static void getPaths(int[][]A, int i, int j, ArrayList<Integer> path, ArrayList<ArrayList<Integer>> allPaths) {
        int n = A.length;
        if (i>=n || j>=n) return;

        path.add(A[i][j]);

        if (i==n-1 && j==n-1) {
            allPaths.add(path);
            return;
        }
        getPaths(A, i, j+1, new ArrayList<>(path), allPaths);
        getPaths(A, i+1, j, path, allPaths);
    }

    public static void main(String[] args) {
        ArrayList<ArrayList<Integer>> allPaths = new ArrayList<>();
        getPaths(new int[][] { {1,2,3},{4,5,6},{7,8,9}}, 0,0, new ArrayList<Integer>(), allPaths );
        System.out.println(allPaths);
    }
}
2
Andy897 23 Фев 2015 в 18:28

2 ответа

Лучший ответ

Копия пути на данный момент создается и передается в первом рекурсивном вызове, чтобы в путь можно было добавить дополнительные записи. Нам не нужно передавать его во втором вызове, поскольку любые записи, которые будут добавлены в результате второго вызова, являются частью пути первого вызова.

3
Walt 23 Фев 2015 в 15:39

Они представляют собой два пути, отличных от текущего. Итак, new ArrayList <> (path) используется для создания копии текущего пути в одном направлении, а просто путь передается для завершения текущего пути в другом направлении.

По сути, поскольку вы хотите заполнить два разных участка, вы не можете использовать текущий для вставки двух разных путей в один и тот же массив. Таким образом, вы передаете копию в одном из вызовов, чтобы этот путь находился в другой области памяти, чтобы оба пути, которые разделяются в текущей точке, могли вычисляться независимо.

1
jbernardo 23 Фев 2015 в 15:34