leetcode上涉及到的全排列,注意数组的有序,无序,数组元素是否有重复的
主要是递归算法
每个问题记住关键点,注意特殊处理
全排列问题转载
http://blog.youkuaiyun.com/morewindows/article/details/7370155/
求下一序列问题转载
http://www.cnblogs.com/warmland/p/5219217.html
1。 全排列就是从第一个数字起每个数分别与它后面的数字交换
2。 去重的全排列就是从第一个数字起每个数分别与它后面非重复出现的数字交换
3。 求下一序列 4个步骤
从后往前找到第一个不是递增的数字的位置,记录下为p,如果p已经走到尽头,那么直接颠倒所有数字然后返回
从p往后找到比p大的最小的那个数的位置q(第一个比p位置大的)
交换p,q的位置
对于p之后(不包括p)的所有数 逆序
46. Permutations(全排列)
题目地址
https://leetcode.com/problems/permutations/
ac代码要记牢
数组数字不重复,最基础的递归, 直接敲出来
class Solution {
private:
vector<vector<int>> ans;
public:
void recursion(int k,vector<int> nums, int n)
{
if (k >= n)
return;
if (k == n - 1){
/* for (int i = 0; i < n; i++)
cout << nums[i] << " ";
cout << endl;*/
ans.push_back(nums);
}
for (int i = k; i < n; i++)
{
swap(nums[k], nums[i]);
recursion(k + 1, nums, n);
swap(nums[k], nums[i]);
}
}
vector<vector<int>> permute(vector<int>& nums) { // nums是distinct
int n = nums.size();
if (n == 0)
return ans;
recursion(0, nums, n);
return ans;
}
};
47. Permutations II(全排列去重)
题目地址
https://leetcode.com/problems/permutations-ii/
求解思路
去重:可以采用排序判断,set集合等,或者自己写个方法判重
总之记住上面去重的方法
31. Next Permutation(下一序列)
题目地址
https://leetcode.com/problems/next-permutation/
ac代码
class Solution {
public:
void rev(vector<int> &nums, int left, int right){
for (int i = left; i <= (left + right) / 2; i++){
int tmp = nums[i];
nums[i] = nums[right - i + left];
nums[right - i + left] = tmp;
}
}
void nextPermutation(vector<int>& nums) {
int n = nums.size();
if (n <= 1)
return;
int pos = n - 1;
while (pos > 0 && nums[pos-1] >= nums[pos]){ // 从后往前递增,等号问题
pos--;
}
if (pos > 0){
//int val = nums[pos - 1];
// 找到val之后的比 val大的最小的一个数
int j = n - 1;
while (nums[j] <= nums[pos-1]){
j--;
}
// swap
int tmp = nums[j];
nums[j] = nums[pos-1];
nums[pos-1] = tmp;
// reverse val之后的所有数
rev(nums, pos, n - 1);
}
else{
rev(nums, 0, n - 1);
}
}
};
60. Permutation Sequence
题目地址
https://leetcode.com/problems/permutation-sequence/
题目求解
求序列的第k个序列
利用数字规律,递归求解,全排列共n!种
class Solution {
public:
string ans;
vector<int> jieceng;
void dfs(string v, int n, int k) //递归
{
if (n == 0)
return;
int index = n - 1;
for (int i = 1; i < n; i++)
{
if (k <= i * jieceng[n - 1])
{
index = i - 1;
break;
}
}
//printf("%c",v[index]);
ans += v[index];
v.erase(v.begin() + index);
dfs(v, n - 1, k - index*jieceng[n - 1]);
}
string getPermutation(int n, int k) {
ans = "";
jieceng.resize(n + 1);
jieceng[0] = 1;
for (int i = 1; i <= n; i++)
{
jieceng[i] = jieceng[i - 1] * i;
}
if (k <= 0 || k > jieceng[n])
{
return ans;
}
string s = "";
for (int i = 1; i <= n; i++)
s += (i + '0');
dfs(s, n, k);
return ans;
}
};