leetcode 47. Permutations II
全排列数组
为了得到最快的速度和最小的空间;先计算结果需要容纳多大的数组;

int GetCMN(int m, int n) { if (n == m || n == 0) return 1; int mm = 1; n = m -n > n?n:m-n; for (int i = 1; i <= n; ++i) { mm *= m; --m; } int nn = 1; while (n > 0) { nn *= n; --n; } return mm / nn; } int GetCount(vector<int>& nums) { int count = 1; for (int i = 0; i < nums.size(); ++i) { int n = 1; int m = nums.size() - i; while (i + 1 < nums.size() && nums[i] == nums[i + 1]) { ++i; ++n; } count *= GetCMN(m, n); } return count; }
获取该数组的全排列
vector<vector<int>> permuteUnique(vector<int>& nums) { vector<vector<int>> result; if (nums.size() == 0) return result; sort(nums.begin(), nums.end()); //cout << GetCount(nums) << endl; nums.reserve(GetCount(nums)); do { result.push_back(nums); } while (next_permutation(nums.begin(), nums.end())); return result; }
这里用到了stl里面的next_permutation函数;该意思是下一个排列组合方式;其实是找到下一个比当前序列大的数组,比如:{1,1,2,2,3,3,3}下一个比当前大的:{1,1,2,3,2,3,3};
通过查看该源码可以发现,具体的实现方式;大致如下所示
bool __next_permutation(vector<int>::iterator first, vector<int>::iterator last) { auto i = last; if (first == last || first == --i) return false; while (true) { auto p = i; if (*--i < *p) { auto j = last; while (*i >= *--j); swap(*i, *j); reverse(p, last); return true; } if (i == first) { reverse(first, last); return false; } } }
1、从右往左遍历到第一个比自己小的数字;本身位置记为p,它左边位置记为i;
2、寻找要跟i调换位置数字;从右往左找到第一个比*i 大的位置记为j;
3、将i和j的值互换;这样从右往左到达p依旧是递增的序列;
4、将p到结尾的数组进行翻转,则产生了全新的从小到大排列的数组;则可以进行下一轮全新的排列;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!