LeetCode(46):全排列
Posted Ariel_一只猫的旅行
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode(46):全排列相关的知识,希望对你有一定的参考价值。
Medium!
题目描述:
给定一个没有重复数字的序列,返回其所有可能的全排列。
示例:
输入: [1,2,3] 输出: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ]
解题思路:
这道题是求全排列问题,给的输入数组没有重复项,这跟之前的那道 Combinations 组合项 和类似,解法基本相同,但是不同点在于那道不同的数字顺序只算一种,是一道典型的组合题,而此题是求全排列问题,还是用递归DFS来求解。这里我们需要用到一个visited数组来标记某个数字是否访问过,然后DFS递归函数循环应从头开始,而不是从level开始,这是和 Combinations 组合项 不同的地方,其余思路大体相同。
C++解法一:
1 class Solution { 2 public: 3 vector<vector<int> > permute(vector<int> &num) { 4 vector<vector<int> > res; 5 vector<int> out; 6 vector<int> visited(num.size(), 0); 7 permuteDFS(num, 0, visited, out, res); 8 return res; 9 } 10 void permuteDFS(vector<int> &num, int level, vector<int> &visited, vector<int> &out, vector<vector<int> > &res) { 11 if (level == num.size()) res.push_back(out); 12 else { 13 for (int i = 0; i < num.size(); ++i) { 14 if (visited[i] == 0) { 15 visited[i] = 1; 16 out.push_back(num[i]); 17 permuteDFS(num, level + 1, visited, out, res); 18 out.pop_back(); 19 visited[i] = 0; 20 } 21 } 22 } 23 } 24 };
还有一种递归的写法,更简单一些,这里是每次交换num里面的两个数字,经过递归可以生成所有的排列情况,代码如下。
C++解法二:
1 class Solution { 2 public: 3 vector<vector<int> > permute(vector<int> &num) { 4 vector<vector<int> > res; 5 permuteDFS(num, 0, res); 6 return res; 7 } 8 void permuteDFS(vector<int> &num, int start, vector<vector<int> > &res) { 9 if (start >= num.size()) res.push_back(num); 10 for (int i = start; i < num.size(); ++i) { 11 swap(num[start], num[i]); 12 permuteDFS(num, start + 1, res); 13 swap(num[start], num[i]); 14 } 15 } 16 };
最后再来看一种方法,这种方法是CareerCup书上的方法,也挺不错的,这道题是思想是这样的:
当n=1时,数组中只有一个数a1,其全排列只有一种,即为a1
当n=2时,数组中此时有a1a2,其全排列有两种,a1a2和a2a1,那么此时我们考虑和上面那种情况的关系,我们发现,其实就是在a1的前后两个位置分别加入了a2
当n=3时,数组中有a1a2a3,此时全排列有六种,分别为a1a2a3, a1a3a2, a2a1a3, a2a3a1, a3a1a2, 和 a3a2a1。那么根据上面的结论,实际上是在a1a2和a2a1的基础上在不同的位置上加入a3而得到的。
_ a1 _ a2 _ : a3a1a2, a1a3a2, a1a2a3
_ a2 _ a1 _ : a3a2a1, a2a3a1, a2a1a3
C++解法三:
1 class Solution { 2 public: 3 vector<vector<int> > permute(vector<int> &num) { 4 if (num.empty()) return vector<vector<int> >(1, vector<int>()); 5 vector<vector<int> > res; 6 int first = num[0]; 7 num.erase(num.begin()); 8 vector<vector<int> > words = permute(num); 9 for (auto &a : words) { 10 for (int i = 0; i <= a.size(); ++i) { 11 a.insert(a.begin() + i, first); 12 res.push_back(a); 13 a.erase(a.begin() + i); 14 } 15 } 16 return res; 17 } 18 };
以上是关于LeetCode(46):全排列的主要内容,如果未能解决你的问题,请参考以下文章
[Leetcode 46]全排列 Permutations 递归