回溯演算法框架
阿新 • • 發佈:2020-10-26
回溯演算法就是將每一種可能遍歷一遍,而且每一種結果都不相同
解決一個回溯問題,實際上就是解決一個決策樹的遍歷過程
我們需要思考三個問題:
- 路徑:已經做出的選擇,將來要儲存到結果的路徑
- 選擇列表:當前可以做的選擇
- 結束條件:就是遍歷到達末尾時候的條件
解決回溯演算法有一個框架:
LinkedList<LinkedList<元素型別>> 結果集 = new LinkedList<>(); private void backtrack(路徑, 選擇列表) { for (元素型別 o : 選擇列表) { if (到達末尾) { 將選擇列表新增到結果集中; } 做選擇; backtrack(路勁, 選擇列表); 撤銷選擇; } }
回溯演算法的最核心的框架就是這段虛擬碼了,在迴圈中進行遞迴,在遞迴前做選擇,在遞迴結束後撤銷選擇,到達末尾就將所做的選擇新增到結果集中
利用回溯,可以實現全排列問題:
import java.util.LinkedList; public class Test { private static LinkedList<LinkedList<Integer>> res = new LinkedList<>(); public static void main(String[] args) { int[] nums = {1, 2, 3, 4, 5, 6, 7, 8}; LinkedList<LinkedList<Integer>> list = permutation(nums); System.out.println(list.size()); } private static LinkedList<LinkedList<Integer>> permutation(int[] nums) { LinkedList<Integer> track = new LinkedList<>(); backtrack(nums, track); return res; } private static void backtrack(int[] nums, LinkedList<Integer> track) { // 如果到達了末尾就將結果新增到res連結串列中 if (nums.length == track.size()) { res.add(new LinkedList<>(track)); return; } for (int i : nums) { //如果遍歷過了就跳過 if (track.contains(i)) { continue; } track.add(i); backtrack(nums, track); track.removeLast(); } } }