算法模板 回溯算法

回溯算法

排列

List<LinkedList<Integer>> res = new LinkedList<List<Integer>>();
public void backtrack(int[] nums,LinkedList<Integer> track) {
    
    
	if(track.size() == nums.length) {
    
    
		res.add(new LinkedList(track));
		return;
		
	}
	for (int i=0;i<nums.length;i++) {
    
    
		if(track.contains(nums[i])) {
    
    
			continue;
		}
		track.add(nums[i]);
		//进入下一层决策树
		backtrack(nums, track);
		track.removeLast();
	}
}
public List<List<Integer>> permute(int[] nums) {
    
    
     List<Integer> track = new LinkedList<Integer>();
     backtrack(nums,track);
     return res;
 }

组合

//	记录所有组合
List<List<Integer>> res = new LinkedList<List<Integer>>();
//主函数
public List<List<Integer>> combine(int n,int k){
    
    
	if(k<=0 || n<=0) {
    
    
		return res;
	}
	List<Integer> track = new LinkedList<Integer>();
	backtrack(n,k,1,track);
	return res;
}
//回溯模板
public void backtrack(int n,int k,int start,List<Integer> track) {
    
    
	//到达叶子节点才更新res
	if(track.size()==k) {
    
    
		res.add(new LinkedList(track));
		return;
	}
	//i从start开始递增
	for(int i=start;i<=n;i++) {
    
    
		//做选择
		track.add(i);
		//递归回溯
		backtrack(n,k,i+1,track);
		//撤销选择
		track.remove(track.size()-1);
	}
}

变量 track所指向的列表 在深度优先遍历的过程中只有一份 ,深度优先遍历完成以后,回到了根结点,成为空列表。

在 Java 中,参数传递是 值传递,对象类型变量在传参的过程中,复制的是变量的地址。这些地址被添加到 res 变量,但实际上指向的是同一块内存地址,因此我们会看到 66 个空的列表对象。解决的方法很简单,在 res.add(track); 这里做一次拷贝即可。
res.add(new LinkedList(track));

猜你喜欢

转载自blog.csdn.net/a12355556/article/details/114302102