回溯----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); //从末尾元素开始删除
            }
        }
    }
}
相关推荐
Young_Zn_Cu30 分钟前
Windows安装虚拟机遇到内容解码失败
linux·windows·ubuntu
Digitally4 小时前
如何轻松将 Windows 10 或 11 PC恢复出厂设置
windows
oioihoii7 小时前
深入浅出理解WaitForSingleObject:Windows同步编程核心函数详解
windows·stm32·单片机
xienda10 小时前
Windows CMD命令大全
windows
九伯都19 小时前
rabbitmq的安装和使用-windows版本
windows·分布式·rabbitmq
你我约定有三21 小时前
分布式微服务--万字详解 微服务的各种负载均衡全场景以注意点
java·开发语言·windows·分布式·微服务·架构·负载均衡
程序视点1 天前
电脑硬件检测必备!图吧工具箱11年免费良心软件!100+免费工具合集
前端·windows·后端
云心雨禅1 天前
修改Windows鼠标滚轮方向
windows·计算机外设
程序视点1 天前
2025最佳Windows优化工具推荐:292KB小工具解决Win11右键菜单/自动更新/Defender等12大痛点
windows·性能优化
SHUIPING_YANG1 天前
windows软件ARM64和AMD64(x64)区别,如何查看电脑支持哪种
windows·电脑