回溯----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); //从末尾元素开始删除
            }
        }
    }
}
相关推荐
小猫挖掘机(绝版)2 小时前
通过tailscale实现一台电脑上vscode通过ssh连接另一台电脑上的VMware Linux 虚拟机
linux·windows·vscode·ubuntu·ssh
你我约定有三8 小时前
java--泛型
java·开发语言·windows
self_myth9 小时前
[特殊字符] 深入理解操作系统核心特性:从并发到分布式,从单核到多核的全面解析
windows·macos·wpf·harmonyos
十五年专注C++开发10 小时前
cargs: 一个轻量级跨平台命令行参数解析库
linux·c++·windows·跨平台·命令行参数解析
小韩博11 小时前
Windows权限提升(二)
windows·网络安全·github
CookieCrusher14 小时前
数据泄露危机逼近:五款电脑加密软件为企业筑起安全防线
运维·数据库·windows·安全·文件加密·数据防泄漏·dlp
lvcoc20 小时前
unity 接入火山引擎API,包括即梦AI
windows·unity·ai·火山引擎
vortex51 天前
AD渗透中服务账号相关攻击手法总结(Kerberoasting、委派)
windows·网络安全·渗透测试·ad
一点都不方女士1 天前
《无畏契约》游戏报错“缺少DirectX”?5种解决方案(附DirectX修复工具)
windows·游戏·microsoft·动态链接库·directx·运行库