Loading

回溯算法框架

回溯算法就是将每一种可能遍历一遍,而且每一种结果都不相同

解决一个回溯问题,实际上就是解决一个决策树的遍历过程

我们需要思考三个问题:

  • 路径:已经做出的选择,将来要存储到结果的路径
  • 选择列表:当前可以做的选择
  • 结束条件:就是遍历到达末尾时候的条件

解决回溯算法有一个框架:

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();
		}	
	}
}
posted @ 2020-10-26 17:29  linzeliang  阅读(367)  评论(0)    收藏  举报