当前位置: 首页 > news >正文

LeetCode 剑指 Offer II 083. 没有重复元素集合的全排列

给定一个不含重复数字的整数数组 nums ,返回其 所有可能的全排列 。可以 按任意顺序 返回答案。

示例 1:

输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

1 <= nums.length <= 6
-10 <= nums[i] <= 10
nums 中的所有整数 互不相同

解法一:直接使用STL:

class Solution {
public:vector<vector<int>> permute(vector<int>& nums) {// next_permutation函数每次产生下一个排列// 下一个排列的含义是按字典顺序下一个更大的排列// 因此需要先对nums进行从小到大排序sort(nums.begin(), nums.end());vector<vector<int>> ans;do {ans.push_back(nums);} while (next_permutation(nums.begin(), nums.end()));return ans;}
};

如果输入数组大小为n,此算法时间复杂度为O(n*n!),空间复杂度为O(1)。next_permutation函数的时间复杂度最多为O(n)。

解法二:回溯法,遍历某个排列的每一个元素,当遍历到下标i时,我们遍历所有可以放到下标i的元素,但有些元素在前面已经用过了,因此我们维护一个visited数组,如果该元素没有用过,才放到下标i:

class Solution {
public:vector<vector<int>> permute(vector<int>& nums) {vector<vector<int>> ans;unordered_set<int> visited;vector<int> current;backtrack(0, current, nums, visited, ans);return ans;}private:void backtrack(int pos, vector<int> current, vector<int> &nums, unordered_set<int> &visited, vector<vector<int>> &ans) {int sz = nums.size();if (pos == sz) {ans.push_back(current);}for (int i = 0; i < sz; ++i) {if (visited.find(nums[i]) != visited.end()) {continue;}visited.insert(nums[i]);current.push_back(nums[i]);backtrack(pos + 1, current, nums, visited, ans);current.pop_back();visited.erase(nums[i]);}}
};

如果输入数组大小为n,此算法时间复杂度为O(n*n!),空间复杂度为O(n)。backtrack函数的调用次数为O(n!),每次调用中,会循环n次。对于空间复杂度,递归深度为n,主要开销是栈空间开销和current、visited数组开销。

解法三:在解法二中,我们使用了visited数组来标记哪些元素已经被全排列过了,我们可以直接修改nums数组,当遍历到下标i时,我们可以令[0,i]的所有元素都是已经全排列过的元素,具体做法是将当前循环中要排列的元素和下标为i的元素交换:

class Solution {
public:vector<vector<int>> permute(vector<int>& nums) {vector<vector<int>> ans;backtrack(0, nums, ans);return ans;}private:void backtrack(int pos, vector<int> &nums, vector<vector<int>> &ans) {int sz = nums.size();if (pos == sz) {ans.push_back(nums);}for (int i = pos; i < sz; ++i) {swap(nums[i], nums[pos]);backtrack(pos + 1, nums, ans);swap(nums[i], nums[pos]);}}
};

如果输入数组大小为n,此算法时间复杂度为O(n*n!),空间复杂度为O(n)。backtrack函数的调用次数为O(n!),每次调用中,会循环n次。对于空间复杂度,递归深度为n,主要开销是栈空间开销。

http://www.lryc.cn/news/28999.html

相关文章:

  • JSONObject与JSONArray使用区别
  • 经典C程序例程:通过进程ID得到文件名
  • 【Java】Spring MVC程序开发
  • leetcode题解-704. 二分查找
  • 2.2 C语言程序的错误条件
  • laravel 邮件发送
  • 高性能 Jsonpath 框架,Snack3 3.2.57 发布
  • Android---进程间通信机制3
  • Python实战,爬取金融期货数据
  • Allegro如何导入第三方网表操作指导
  • 高码率QPSK调制解调方案(FPGA实现篇)
  • Elasticsearch的RESTful Api使用
  • 软著申请需要注意的
  • SpringBoot入门 - 添加Logback日志
  • 社会实践报告
  • LeetCode 460. LFU 缓存 -- 哈希查询+双向链表
  • Dubbo 源码分析 – SPI 机制
  • JDBC概述二(JDBC编程+案例展示)
  • 广度和深度优先搜索解析与示例代码
  • 基于SLIC超像素的归一化分割算法
  • C语言刷题(4)——“C”
  • 带你看懂RuoYi动态数据源切换
  • 家有女儿必看:盲目的和青春期女儿较劲,不如掌握4个沟通技巧
  • 【VC 7/8】vCenter Server 基于文件的备份和还原Ⅰ——基于文件的备份和还原的注意事项和限制
  • 【ROS学习笔记10】ROS中配置自定义Cpp头文件和导入自定义Python库
  • svn 分支(branch)和标签(tag)管理
  • @Transactional详解
  • 机器学习:Transformer
  • pytorch-模型构建,参数访问,模型存取API接口,对比学习
  • javaEE 初阶 — 数据链路层中的以太网数据帧