1. 程式人生 > 實用技巧 >回溯演算法框架

回溯演算法框架

回溯演算法就是將每一種可能遍歷一遍,而且每一種結果都不相同

解決一個回溯問題,實際上就是解決一個決策樹的遍歷過程

我們需要思考三個問題:

  • 路徑:已經做出的選擇,將來要儲存到結果的路徑
  • 選擇列表:當前可以做的選擇
  • 結束條件:就是遍歷到達末尾時候的條件

解決回溯演算法有一個框架:

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();
		}	
	}
}