回溯----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); //从末尾元素开始删除
            }
        }
    }
}
相关推荐
tobebetter952721 分钟前
How to manage python versions on windows
开发语言·windows·python
q***71852 小时前
windows下安装并使用node.js
windows·node.js
q***92513 小时前
Windows上安装Go并配置环境变量(图文步骤)
开发语言·windows·golang
凭栏落花侧5 小时前
打印机脱机状态应该怎么处理
windows
q***57746 小时前
MySQL 实验1:Windows 环境下 MySQL5.5 安装与配置
windows·mysql·adb
q***31837 小时前
Windows安装Rust环境(详细教程)
开发语言·windows·rust
q***82919 小时前
windows同时安装两个不同版本的Mysql
windows·mysql·adb
dntktop9 小时前
搜索+计算+插件…这个“全能管家”让你告别80%的桌面图标
运维·windows·自动化·编辑器
h***346310 小时前
Redis安装教程(Windows版本)
数据库·windows·redis
a***131411 小时前
redis存取list集合
windows·redis·list