【leetcode】 Permutations II
来源:互联网 发布:网络剧花千骨主角 编辑:程序博客网 时间:2024/06/06 13:34
From : https://leetcode.com/problems/permutations-ii/
Given a collection of numbers that might contain duplicates, return all possible unique permutations.
For example,[1,1,2]
have the following unique permutations:[1,1,2]
, [1,2,1]
, and [2,1,1]
.
Solution :
思路:采用字典序的非递归方法。从字典顺序最小的一种排列开始,每次获得字典序刚好比前一个排列大的排列,直到得到字典序最大的排列时,就得到了所有的结果,以字符串"abc"为例,"abc"是字典序最小的排列,所有情况按字典序排列为"abc","acb","bac","bca","cba","cab"。
具体步骤为为:
1.字符串进行排序,得到字符串的最小字典序排列(C0C1C2...Cn),Ci<=Ci+1。
2.从后往前,找到一对相邻的升序元素CiCi+1,(Ci<Ci+1),如果遍历完字符串找不到这样的相邻升序对,说明已经达到了字典序最大的全排列
3.从字符串结束位置到位置i遍历,找到比Ci大的元素Cj,交换Cj的位置
4.将Ci+1到Cn所有的字符逆序,这样得到的排列刚好比之前的字典序大(因为转换后Ci+1<Ci+2<...<Cn,为最小字典序)。
5.重复3,4,5过程直到字典序最大。
class Solution {public: void swap(int &i,int &j) { i ^= j; j ^= i; i ^= j; } vector<vector<int>> permuteUnique(vector<int> &num) { vector<vector<int>> res; int i, j, n=num.size(); sort(num.begin(),num.end()); res.push_back(num); while(true) { for(i=n-2; i>=0; i--) if(num[i] < num[i+1]) break; if(i<=-1) return res; for(j=n-1; j>i; j--) if(num[j] > num[i]) break; swap(num[i],num[j]); for(int k=i+1; k<(i+1+n)/2; k++) swap(num[k], num[n-(k-i)]); res.push_back(num); } return res; }};
精简优化一下结构:
public class Solution { public List<List<Integer>> permuteUnique(int[] nums) { List<List<Integer>> ans = new ArrayList<List<Integer>>(); Arrays.sort(nums); do { ans.add(toList(nums)); } while(hasNextPermute(nums)); return ans; } private boolean hasNextPermute(int[] nums) { int len = nums.length, j = len-2, k = len-1; while(j>=0 && nums[j]>=nums[j+1]) --j; if(j == -1) { return false; } for(int n=nums[j]; n>=nums[k]; --k) {} swap(nums, k, j); swapAll(nums, j+1, len-1); return true; } private void swap(int[] nums, int i, int j) { int t = nums[i]; nums[i] = nums[j]; nums[j] = t; } private void swapAll(int[] nums, int i, int j) { while(i < j) { swap(nums, i++, j--); } } private List<Integer> toList(int[] nums) { List<Integer> list = new ArrayList<Integer>(); for(int i=0; i<nums.length; ++i) { list.add(nums[i]); } return list; }}
先对数组进行排序,这样在DFS的时候,可以先判断前面的一个数是否和自己相等,相等的时候则前面的数必须使用了,自己才能使用,这样就不会产生重复的排列了。
class Solution {public: void dfs(int dep, vector<int> &num) { if(dep == n) { ans.push_back(cur); return; } for(int i = 0; i < n; i++) { if (canUse[i]) { if (i != 0 && num[i] == num[i-1] && canUse[i-1]) continue; canUse[i] = false; cur[dep] = num[i]; dfs(dep + 1, num); canUse[i] = true; }} } vector<vector<int>> permuteUnique(vector<int> &num) {n = num.size(); sort(num.begin(), num.end());cur = vector<int>(n);canUse = vector<bool>(n, true); ans.clear(); dfs(0, num); return ans; }private:int n; vector<bool> canUse; vector<int> cur; vector<vector<int> > ans;};
public class Solution { public List<List<Integer>> permuteUnique(int[] nums) { Arrays.sort(nums); List<List<Integer>> ans = new ArrayList<List<Integer>>(); boolean[] used = new boolean[nums.length];dfs(nums, 0, used, new int[nums.length], ans);return ans; } private void dfs(int[] nums, int index, boolean[] used, int[] cur, List<List<Integer>> ans) {if(index == nums.length) {ans.add(toList(cur));return;}for(int i=0; i<nums.length; ++i) { if(used[i] || i > 0 && nums[i]==nums[i-1] && !used[i-1]) continue;used[i] = true;cur[index] = nums[i];dfs(nums, index+1, used, cur, ans);used[i] = false;}}private List<Integer> toList(int[] nums) {List<Integer> l = new ArrayList<Integer>();for(int i : nums) {l.add(i);}return l;}}
- 【LeetCode】Permutations && Permutations II
- leetcode: Permutations/Permutations II
- leetcode Permutations & Permutations II
- [Leetcode]Permutations && Permutations II
- Leetcode: Permutations and Permutations II
- leetcode-permutations and permutations II
- Leetcode:Permutations与Permutations II
- LeetCode: Permutations II
- LeetCode Permutations II
- LeetCode: Permutations II
- [Leetcode] Permutations II
- [LeetCode] Permutations II
- [Leetcode] Permutations II
- leetcode Permutations II
- [LeetCode]Permutations II
- leetcode - Permutations II
- LeetCode-Permutations II
- [leetcode] Permutations II
- 大型网站系统架构的演化
- 阿里云·一面没回答清楚的问题盖戳留念(答案随时更新)
- QT 下OpenCV显示图片
- 特效字幕(ass)简易制作教程
- 关于文件的上传下载问题
- 【leetcode】 Permutations II
- C语言中的运算符1
- http权威指南(一)-Http概述
- 拉格朗日对偶性
- 自己写一个第三方分享库(一)
- 罗马数字
- 【架构设计】MVP与MVC,实现Android应用层开发
- playfair密码java实现
- 继承