【LeetCode-中等题】46. 全排列

文章目录

组合+并集问题汇总:

1、子集去重版本
2、组合去重版本
3、子集非去重版本

题目

这题中nums中的数各不相同,所以不需要去重:

而下面这题,nums中的数会存在重复值,就需要去重:

参考讲解视频:代码随想录---全排列不去重版本

方法一:递归+回溯

关键在于递归之后还要还原做回溯动作:

java 复制代码
	path.add(nums[i]);//加入子结果集
    usered[i] = true;//将该位置标志位标为true  往下不能取了
    backtrace(nums,path,usered);//往下面继续递归
    usered[i] = false;//某次递归结束后,要回溯回去,就得把之前该的标志位还原
    path.remove(path.size()-1);//某次递归结束后,要回溯回去,当前path应该把递归之前加的元素给剔除掉

所以最后,我们统计到的res才是不断扩增结果集的,而usered标志数组和list子集合其实都是中间临时的,是会随着递归改变,并且随着回溯复原的,所以程序最后list子集合肯定是空的,并且标志数组也是初始化的时候的样子

所以在这句代码中的 res.add(new ArrayList<>(path))将子集合加入到结果集的时候就需要将满足条件的子结果集复制一份再放到最终结果集

java 复制代码
      if(path.size() == nums.length) {//递归出口(子结果集大小 = 数组大小 )
        res.add(new ArrayList<>(path));//因为path是实时变化的,必须要将path复制到一个新数组再放到res结果集
        return;
      }

如果我们这样做: res.add(path); ,直接将子结果集放到最终结果集,就会导致加入的子结果集为空,因为path子集合因为会做回溯操作 ,最后肯定加入的就是一个空数组,,满足条件的path只是一个中间状态。

java 复制代码
class Solution {
    List<List<Integer>> res = new ArrayList<>();//最后的结果集
    public List<List<Integer>> permute(int[] nums) {
      List<Integer> path = new ArrayList<>(); //子结果集
      boolean[] usered = new boolean[nums.length]; //标记数组

      backtrace(nums,path,usered);

      return res;
    }

    public void backtrace(int[] nums ,List<Integer> path ,boolean[] usered){
      if(path.size() == nums.length) {//递归出口(子结果集大小 = 数组大小 )
        res.add(new ArrayList<>(path));//因为path是实时变化的,必须要将path复制到一个新数组再放到res结果集
        return;
      }
      for(int i = 0 ; i < nums.length ; i++){
        if(usered[i]) continue;//如果标志位为true  则直接跳过
        else{
          path.add(nums[i]);//加入子结果集
          usered[i] = true;//将该位置标志位标为true  往下不能取了
          backtrace(nums,path,usered);//往下面继续递归
          usered[i] = false;//某次递归结束后,要回溯回去,就得把之前该的标志位还原
          path.remove(path.size()-1);//某次递归结束后,要回溯回去,当前path应该把递归之前加的元素给剔除掉
        }
      }

    }
}
相关推荐
爱吃生蚝的于勒2 小时前
C语言内存函数
c语言·开发语言·数据结构·c++·学习·算法
吾店云建站5 小时前
WordPress 6.7 “Rollins”发布
科技·程序人生·职场和发展·创业创新·程序员创富
ChoSeitaku7 小时前
链表循环及差集相关算法题|判断循环双链表是否对称|两循环单链表合并成循环链表|使双向循环链表有序|单循环链表改双向循环链表|两链表的差集(C)
c语言·算法·链表
DdddJMs__1357 小时前
C语言 | Leetcode C语言题解之第557题反转字符串中的单词III
c语言·leetcode·题解
Fuxiao___7 小时前
不使用递归的决策树生成算法
算法
我爱工作&工作love我7 小时前
1435:【例题3】曲线 一本通 代替三分
c++·算法
白-胖-子8 小时前
【蓝桥等考C++真题】蓝桥杯等级考试C++组第13级L13真题原题(含答案)-统计数字
开发语言·c++·算法·蓝桥杯·等考·13级
workflower8 小时前
数据结构练习题和答案
数据结构·算法·链表·线性回归
好睡凯8 小时前
c++写一个死锁并且自己解锁
开发语言·c++·算法
Sunyanhui18 小时前
力扣 二叉树的直径-543
算法·leetcode·职场和发展