Fork me on GitHub

leetcode之46. 全排列

题目描述:

给定一个没有重复数字的序列,返回其所有可能的全排列。

示例:

1
2
3
4
5
6
7
8
9
10
11
> 输入: [1,2,3]
> 输出:
> [
> [1,2,3],
> [1,3,2],
> [2,1,3],
> [2,3,1],
> [3,1,2],
> [3,2,1]
> ]
>

解题思路一:

时间复杂度:$O(nlogn)$, 空间复杂度:$O(n)$.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution {
public:
vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int> > vec;

if(nums.size() == 0) return vec;


sort(nums.begin(), nums.end(), [](int a, int b){return a < b;});
vec.push_back(nums);

while(next_permutation(nums.begin(), nums.end())) vec.push_back(nums);


return vec;
}
};

解题思路二:

时间复杂度:$O(nlogn)$, 空间复杂度:$O(n)$.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
class Solution {
public:
vector<vector<int>> permute(vector<int>& nums)
{
vector<vector<int> > vec;
if(nums.size() == 0) return vec;

sort(nums.begin(), nums.end(), [](int a, int b){return a < b;});
vec.push_back(nums);
// 自定义下一个全排列
while(find(nums)) vec.push_back(nums);

return vec;
}

bool find(vector<int>& nums)
{
int sw1 = -1, sw2 = -1;
// 从后往前找到第一个比后面数小的,记做sw1.
for(int i = nums.size() - 2; i >= 0; i--)
{
if(nums[i] < nums[i + 1])
{
sw1 = i;
break;
}
}
if(sw1 == -1) return false;
// 从后往前找到第一个比sw1数大的,记做sw2.
for(int j = nums.size() - 1; j > sw1; j--)
{
if(nums[j] > nums[sw1])
{
sw2 = j;
break;
}
}
// 交换sw1和 sw2
swap( nums[sw1], nums[sw2]);
// sw1之后的数进行排序
sort(nums.begin() + sw1 + 1, nums.end());

return true;
}
};