BM55 没有重复项数字的全排列
描述
给出一组数字,返回该组数字的所有排列例如:[1,2,3]的所有排列如下
[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2], [3,2,1].
(以数字在数组中的位置靠前为优先级,按字典序排列输出。)
数据范围:数字个数 要求:空间复杂度
,时间复杂度
示例1
输入:
[1,2,3]
复制返回值:
[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
复制
示例2
输入:
[1]
复制返回值:
[[1]]
题解
递归解法
思路:
假设一个数组有n个元素,我们每次从中取出一个元素,然后将剩余的元素进行全排列,那么整个数组的全排列就是这n个元素分别和剩余元素的组合。
注意:这里没有进行去重,也100%过了,可能是测试用例都不含有重复元素,或者本身的没有重复项的全排列中的没有重复项并不是指排列项不能有重复的~~
代码如下:
std::vector<std::vector<int>> perm_imp(std::vector<int> num)
{
std::vector<std::vector<int>> res;
if (num.size() == 0)
{
return res;
}
if (num.size() == 1)
{
res.push_back(num);
return res;
}
for (int i = 0; i < num.size(); ++i)
{
std::vector<int> cur = num;
cur.erase(cur.begin() + i);
auto cur_perm = perm_imp(cur);
for (auto &x : cur_perm)
{
x.push_back(num[i]);
res.push_back(x);
}
}
return res;
}
std::vector<std::vector<int>> permute(std::vector<int> &num)
{
auto ans = perm_imp(num);
// 将返回值根据题目要求进行排序
std::sort(ans.begin(), ans.end(), [](std::vector<int> &a, std::vector<int> &b)
{
for (int i = 0; i < a.size();++i)
{
if (a[i] < b[i])
{
return true;
}
else if (a[i] > b[i])
{
return false;
}
}
return false; });
return ans;
}
int main()
{
std::vector<int> num{1, 2, 3};
permute(num);
return 0;
}
官方题解
很明显,官方题解更加优秀。
- 没有用额外的空间存放输入的数组
- 先对输入数组排序,优于对结果排序
class Solution {
public:
void recursion(vector<vector<int> > &res, vector<int> &num, int index){
//分枝进入结尾,找到一种排列
if(index == num.size() - 1)
res.push_back(num);
else{
//遍历后续的元素
for(int i = index; i < num.size(); i++){
//交换二者
swap(num[i], num[index]);
//继续往后找
recursion(res, num, index + 1);
//回溯
swap(num[i], num[index]);
}
}
}
vector<vector<int> > permute(vector<int> &num) {
//先按字典序排序
sort(num.begin(), num.end());
vector<vector<int> > res;
//递归获取
recursion(res, num, 0);
return res;
}
};