回溯思想简单理解

回溯思想简单理解

问题说明
	给定一个正整数数组nums,为方便理解,假定数组中不存在重复的整数。
列出这些整数的全排列
	如:nums={1,2,3},那么答案为:
	{{1,2,3},{1,3,2},{2,1,3},{2,3,1},{3,1,2},{3,2,1}}
问题解释
	1. 我们可以直接穷举出所有的排列可能,这也是回溯算法的核心思想,但一般回溯
都会通过剪枝来减少不合理的可能值
	2. 用树结构来理解回溯的思想

在这里插入图片描述

解空间树
	1. 我们不难在脑海中构建这样的一颗树结构,事实上,它对于所有回溯问题都适用
我们构建一个已选择路径的数组track[],它表示已选择的三个数字,也就是已选择的路径,
例如:选择了{1,2},表示第一步选择了数字1,第二步选择了数字2,那么最后一次做选择
时,我们把已选择的路径从nums剔除出去,第三步也就只能选择数字3  	
	3. 一套适合回溯问题的模板
void backtrack(){
	if 满足结束条件	(track数组已满)
		存储结果..return
		
	for 选择 in 选择列表	(nums长度)
		做选择(加入路径)
		递归下一层
		撤销选择
}
我们用一个List<List<Integer>>存放所有结果值,LinkedList<Integer>存放路径
获得全排列主要代码
/**
     * 如果已经走过的路径等于nums长度,那么说明走到底了
     * @param nums:全排列的数字
     * @param track:已经走过的路径
     */
    public static 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();

        }

    }
发布了11 篇原创文章 · 获赞 1 · 访问量 420

猜你喜欢

转载自blog.csdn.net/hhhghh_/article/details/104782256
今日推荐