力扣面试150题--全排列

Day 71

题目描述

思路

回溯这类题还真不好理解 难点在于它的思路是什么,写代码很简单

举个例子 123,我们如何获取它的全排列。如下图

我们聚焦到数组的序号first,我们需要不重复的往这个first填数(并且不重复,考虑从左往右依次填入值),抽象到图里的意思是该空格的元素,依次和空格后的元素交换次序(还有一个不交换的情况)。每次进入下一层时,first+1,然后重复交换的做法,直到first==元素总数(即都指向最后一个元素)。

思路已经有了

我们来看看回溯的做题模板:

java 复制代码
void backtracking(参数) {
    if (终止条件) {
        存放结果;
        return;
    }
    for (选择 : 本层集合中的元素) {
        处理节点;
        backtracking(路径, 选择列表); // 递归
        撤销处理; // 回溯
    }
}

我们来依次填空,首先我们需要一个保存结果的数组res,以及一个存放每种清空的列表te,这些都定义在permute,

首先我们需要确定back函数的参数,res和te肯定需要,我们需要得到空格的位置吧 x,我们需要知道数组的长度吧 n。对于te我们需要提前往里面填入nums的值,因为我们需要不停交换嘛。

其次我们来看终止条件,根据我们上面的分析,只要first==列表元素总数就要要保存te的副本到res中,结束递归。

最后看,循环条件,我们需要从空格位置和其后每个元素交换位置,操作就很明显了就是交换,撤销就是换回来就行,back()移动空格处理。

java 复制代码
class Solution {
    public  static  void back(int x,int n,List<List<Integer>>res,List<Integer>te){
        if(x==n){
            res.add(new ArrayList<Integer>(te));
            return;
        }
        for(int i=x;i<n;i++){
            Collections.swap(te,i,x);
            back(x+1,n,res,te);
            Collections.swap(te,x,i);
        }
    }
    public  static  List<List<Integer>> permute(int[] nums) {
        List<List<Integer>>res = new ArrayList<List<Integer>>();
        List<Integer>te = new ArrayList<Integer>();
        for (int i = 0; i < nums.length; i++) {
            te.add(nums[i]);
        }
        back(0,nums.length,res,te);
        return  res;
    }
}
相关推荐
让我们一起加油好吗28 分钟前
【数论】费马小定理
c++·算法·数论·1024程序员节·费马小定理·逆元
烟袅29 分钟前
告别 var!深入理解 JavaScript 中 var、let 和 const 的差异与最佳实践
javascript·面试
大数据张老师1 小时前
数据结构——冒泡排序
数据结构·算法·排序算法·1024程序员节
m0_748233641 小时前
单调队列【C/C++】
c语言·c++·算法·1024程序员节
大数据张老师1 小时前
数据结构——折半插入排序
数据结构·算法·排序算法·1024程序员节
yi碗汤园2 小时前
【一文了解】八大排序-插入排序、希尔排序
开发语言·算法·unity·c#·1024程序员节
Han.miracle2 小时前
数据结构——排序的超级详解(Java版)
java·数据结构·学习·算法·leetcode·排序算法·1024程序员节
搂鱼1145143 小时前
GJOI 10.20/10.22 题解
算法
我搞slam3 小时前
插入区间--leetcode
算法·leetcode
前进之路93 小时前
Leetcode每日一练--40
算法·leetcode