回溯----1.全排列


**

返回该数组存在的所有访问顺序

大致执行流程:

首先选取一个元素作为起点,保存该元素;再访问下一个元素并保存,重复上述流程,直到访问所有元素;将该路径添加到res中

回溯到上一步,更换访问顺序,直到访问完所有元素;重复上述流程,直到上一步可选元素全部访问完;将该路径添加到res中

回溯到上上步,更换访问顺序,直到访问完所有元素;重复上述流程,直到上一步可选元素全部访问完;将该路径添加到res中

.......

直到回溯到第一步,并访问完所有可选元素,此时得出所有访问顺序

所需参数:

List<Integer> tempResult 临时保存单次结果

int[] used 用于判断可访问元素;访问过对应位置设为1 未访问为0

操作细化:

终止条件:

tempResult长度与nums长度相同;代表访问完所有元素,保存到res中并终止

访问方式(for循环 + 递归):

利用used判断当前元素是否被访问

未访问过则添加到tempResult中,并修改used;访问过则不做处理,迭代元素再次尝试

递归调用添加下一个元素;遇到访问过的元素不做处理,通过for循环迭代元素,可访问才进行处理

回溯:

回退used与tempResult的状态

*/

java 复制代码
class Solution {
    //保存所有结果
    private List<List<Integer>> res = new ArrayList<>();
    //临时保存单次结果
    private List<Integer> tempResult = new ArrayList<>();
    //用于判断可访问元素(元素是否被访问)
    private int[] used; //访问过对应位置设为1 未访问为0


    //避免重复传参
    private int[] nums;

    public List<List<Integer>> permute(int[] nums) {
        /**
            返回该数组存在的所有访问顺序
            大致执行流程:
                    首先选取一个元素作为起点,保存该元素;再访问下一个元素并保存,重复上述流程,直到访问所有元素;将该路径添加到res中
                    回溯到上一步,更换访问顺序,直到访问完所有元素;重复上述流程,直到上一步可选元素全部访问完;将该路径添加到res中
                    回溯到上上步,更换访问顺序,直到访问完所有元素;重复上述流程,直到上一步可选元素全部访问完;将该路径添加到res中
                    .......
                    直到回溯到第一步,并访问完所有可选元素,此时得出所有访问顺序
            所需参数:
                    List<Integer> tempResult 临时保存单次结果
                    int[] used   用于判断可访问元素;访问过对应位置设为1 未访问为0
            操作细化:
                    终止条件:
                            tempResult长度与nums长度相同;代表访问完所有元素,保存到res中并终止
                    访问方式(for循环 + 递归):
                            利用used判断当前元素是否被访问
                            未访问过则添加到tempResult中,并修改used;访问过则不做处理,迭代元素再次尝试
                            递归调用添加下一个元素;遇到访问过的元素不做处理,通过for循环迭代元素,可访问才进行处理
                    回溯:
                            回退used与tempResult的状态
        */

        this.nums = nums;
        this.used = new int[nums.length];

        backtrack();
        return res;
        
    }

    private void backtrack() {
        //代表所有元素都被访问 保存本次结果并return
        if(tempResult.size() == nums.length) {
            //res.add(tempResult); 浅拷贝,会因后续的回溯导致已保存的结果改变
            
            //深拷贝
            res.add(List.copyOf(tempResult));
            return;
        }

        for(int i = 0; i < nums.length; i++) {
            //未被访问过才可添加到tempResult中
            if(used[i] == 0) {
                tempResult.add(nums[i]);
                used[i] = 1; //修改访问状态
                backtrack(); //递归调用,添加下一个元素

                //回溯 回退used与tempResult的状态
                used[i] = 0;
                tempResult.remove(tempResult.size() - 1); //从末尾元素开始删除
            }
        }
    }
}
相关推荐
专注VB编程开发20年7 分钟前
Windows API 所有老式结构体4字节对齐,但是64位VBA,Twinbasic弄成了8字节对齐,大BUG
windows·bug
东篱把酒黄昏22 分钟前
wsl和Windows混合开发高级配置详细指导
windows
helloliyh2 小时前
windows设置定时任务开机执行bat或exe文件
windows
清水白石0082 小时前
从“类型体操”到工程设计:用 Python 解释协变、逆变与不变
网络·windows·python
卷Java3 小时前
上下文压缩
开发语言·windows·python
日取其半万世不竭3 小时前
Minecraft Java版社区服搭建教程(Windows版)
java·开发语言·windows
Deryck_德瑞克5 小时前
Nacos适配Kingbase数据库
数据库·windows
liann1196 小时前
3.3_tasklist和netstat命令详解
运维·windows·计算机网络·安全·信息与通信
sdszoe49227 小时前
Windows server服务器AD+DC网络服务器运维管理方式
运维·服务器·windows·ad+dc·集中式管理·域控制器dc
AI玫瑰助手7 小时前
Python基础:输入input与输出print函数详解
开发语言·windows·python