Я изучаю алгоритм поиска с возвратом, и я увидел, что существует, по сути, один шаблон с двумя тонкими различиями для решения такой проблемы. Я хочу понять, в чем разница между двумя (я вижу на выходе, но не могу понять asp концепцию)
Основная идея c обратного отслеживания: 1) сделайте выбор 2) изучить выбор 3) отменить выбор
Я заметил, что есть два варианта изучения выбора
- вы увеличиваете значение параметра позиции, которое вы получаете в функции обратного отслеживания
- вы увеличиваете индекс l oop и передаете ему функцию отслеживания с возвратом
Позвольте мне сначала представить код, и вы увидите, что разница заключается в передаче параметров.
- Попытка сгенерировать перестановку
При вызове перестановки мы увеличиваем параметр, полученный в функции, и рекурсивно передаем его перестановке.
```
permutation(int first, List<Integer> l) {
if (first == l.size()) {
perms.add(new ArrayList<Integer>(l));
return;
}
for (int i = first; i < l.size(); i++) {
Collections.swap(l, first, i);
permutation(first + 1, l); // increment the value of the position parameter
Collections.swap(l, i, first);
}
Попытка сгенерировать комбинацию из K элементов
При вызове комбинации мы увеличиваем индекс l oop и рекурсивно передаем его в комбинационную функцию
```
combination(List<Integer> nums, int first, int k) {
if (curr.size() == k) {
combos.add(new LinkedList(curr));
return;
}
for (int i = first; i < nums.size(); i++) {
curr.add(nums.get(i));
combination(nums, i + 1, k); // increment the index of the loop
curr.removeLast();// backtrack
}
}
Может пожалуйста, объясните, почему и когда мы решили увеличить индекс l oop и передать его функции отслеживания с возвратом, а не увеличивать параметр функции и передавать его для отслеживания с возвратом. Не только с точки зрения этого кода, но и в целом.
Сохранение рабочей копии кода ниже
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
public class PnC {
public static void main(String[] args) {
List<Integer> nums = Arrays.asList(1,3,2,4);
int k = 3;
combination(nums, 0, 3);
System.out.println("Combinations");
print(combos);
curr.clear();
permutation(0,nums);
System.out.println("Permuations");
print(perms);
}
private static void print(List<List<Integer>> op) {
for (List<Integer> l : op) {// print output
l.stream().forEach(e -> System.out.print(e + ","));
System.out.println();
}
}
static List<List<Integer>> combos = new LinkedList<>();
static LinkedList<Integer> curr = new LinkedList<>();
static List<List<Integer>> perms = new LinkedList<>();
public static void combination(List<Integer> nums, int first, int k) {
// if the combination is done
if (curr.size() == k) {
combos.add(new LinkedList(curr));
return;
}
for (int i = first; i < nums.size(); i++) {
curr.add(nums.get(i));// add i into the current combination
combination(nums, i + 1, k);// use next integers to complete the combination
curr.removeLast();// backtrack
}
}
public static void permutation(int first, List<Integer> l) {
if (first == l.size()) {
perms.add(new ArrayList<Integer>(l));
return;
}
for (int i = first; i < l.size(); i++) {
Collections.swap(l, first, i);
permutation(first + 1, l);
Collections.swap(l, i, first);
}
}
}