回溯----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); //从末尾元素开始删除
            }
        }
    }
}
相关推荐
航Hang*5 分钟前
Windows Server 配置与管理——第3章:文件系统管理
运维·服务器·windows·vmware
无限进步_1 小时前
【C++】电话号码的字母组合:从有限处理到通用解法
开发语言·c++·ide·windows·git·github·visual studio
私人珍藏库2 小时前
【Windows】PDF超能助手(1.0.13)
windows·pdf·工具·软件·多功能
仟人斩2 小时前
Windows 下把 VSCode 加入右键菜单(注册表方案)
windows·vscode·上下文菜单
大强同学2 小时前
对比 VS Code:Zed 编辑器编码体验全面解析
人工智能·windows·编辑器·ai编程
加勒比之杰克6 小时前
从阻塞 IO 到 epoll:把 Linux 网络 IO 一次讲透
linux·网络·windows·select·多路转接·epoll·poll
涔溪7 小时前
腾讯 WorkBuddy 超详细卸载清理文档(适用于 Windows 1011 + macOS 全版本,彻底卸载、不留残留)
windows·macos·ai·workbuddy
取个名字太难了a7 小时前
等待块(一)
windows
洒满阳光的庄园7 小时前
Tauri Windows 桌面端:环境与构建流程
windows
love530love7 小时前
从零搭建本地版 Claurst:基于 Rust 重构的 Claude Code 终端编码助手 + LM Studio 模型接入测试
开发语言·人工智能·windows·重构·rust·lm studio·claude code