首先介绍一下全排列算法
假设有一数列1,2,3,4
那么1,2,3,4的全排列
perm({1,2,3,4})=1perm({2,3,4})+2perm({1,3,4})+3perm({1,2,4})+4perm(1,2,3)
那么我们只要将每个数,与第一个数交换不就可以得到下一个序列了吗?
比如{1,2,3,4}第一个与第二个数交换,那么不就得到2 {1,3,4}了,接下来我们用一个实际的例子说明该程序是怎样运行的
具体算法流程:
数列:{1,2,3} 第一个与第一个交换
可以得到1 {2,3} 将序列{2,3}放进perm函数递归,然后
——递归{2,3}
数列{2,3}第一个与第一个交换
得到2{3} ,输出1,2,3 (此时low=high,因为序列{3}只有一位数,因此输出列表list)
数列{2,3}第一个与第一个交换回来,结果仍然是{2,3}
数列{2,3}第一个与第二个交换
得到3{2},输出1,3,2
{3,2}又第一个与第二个交换回来,变回{2,3}
—–{2,3}递归完毕序列恢复原状{1,2,3}
数列:{1,2,3} 第一个与第二个交换
可以得到2,{1,3}
——递归{1,3}
数列{1,3}第一个与第一个交换
得到1{3} ,输出2,1,3
数列{1,3}第一个与第一个交换回来,结果仍然是{1,3}
数列{1,3}第一个与第二个交换
得到3{1},输出2,3,1
{3,1}又第一个与第二个交换回来,变回{1,3}
—–{1,3}递归完毕
序列{2,1,3}第一个与第二个交换
序列恢复原状{1,2,3}
数列:{1,2,3} 第一个与第三个交换
可以得到3,{1,2}
——递归{1,2}
数列{1,2}第一个与第一个交换
得到1{2} ,输出3,1,2
数列{1,2}第一个与第一个交换回来,结果仍然是{1,2}
数列{1,2}第一个与第二个交换
得到2{1},输出3,2,1
{2,1}又第一个与第二个交换回来,变回{1,2}
—–{1,2}递归完毕
序列{3,1,2}第一个与第二个交换
序列恢复原状{1,2,3}
算法可以简单地写作
perm({1,2,3})=1perm({2,3})+2perm({1,3})+3perm({1,2})
perm({2,3})=2perm({3})+3perm({2})
perm({1,3})=1perm({3})+3perm({1})
perm({1,2})=1perm({2})+2perm({1})
void perm(vector<int>& nums, int low, int high)
{
if (low == high)当low==high时,此时nums就是其中一个排列,输出nums
{
for (int i = 0; i <= low; ++i)
cout << nums[i];
cout << endl;
}
else
{
for (int i = low; i <= high; ++i)//每个元素与第一个元素交换
{
swap(nums[i], nums[low]);
perm(nums, low + 1, high);//交换后,得到子序列,用函数perm得到子序列的全排列
swap(nums[i], nums[low]);//最后,将元素交换回来,复原,然后交换另一个元素
}
}
}
题目:
给定一个可包含重复数字的序列,返回所有不重复的全排列。
示例:
输入: [1,1,2]
输出:
[
[1,1,2],
[1,2,1],
[2,1,1]
]
思路:
就是在上面全排列算法上多了一步去重
有待改进…
class Solution {
private:
vector<vector<int>> res;
bool Count(vector<vector<int>>&nums, vector<int>&t)
{
for (int i = 0; i < nums.size(); ++i)
{
if (nums[i] == t)
return false;
}
return true;
}
public:
void perm(vector<int>& nums, int low, int high)
{
if (low == high)
{
if(Count(res,nums))
res.push_back(nums);
}
else
{
for (int i = low; i <= high; ++i)
{
swap(nums[i], nums[low]);
perm(nums, low + 1, high);
swap(nums[low], nums[i]);
}
}
}
vector<vector<int>> permuteUnique(vector<int>& nums)
{
if (nums .size()==0)
return{ {} };
if (nums.size() == 1)
return{ {nums[0]} };
sort(nums.begin(), nums.end());
perm(nums, 0, nums.size() - 1);
return res;
}
};