您的位置:首页 > 产品设计 > UI/UE

LeetCode-Permutations && unique && next

2017-09-08 10:58 501 查看
Permutation

按照全排列的方式,每次生成后,下一个数字来插孔生成所有的情况,不然使用递归还要标记每个位置,麻烦。

class Solution(object):
def permute(self, nums):
perms = [[]]
for n in nums:
new_perms = []
for perm in perms:
for i in xrange(len(perm)+1):
new_perms.append(perm[:i] +
+ perm[i:])   ###insert n
perms = new_perms
return perms


Next Permutation

从后往前找第一个非逆序数i,即不上升数字(联想到峰值问题,只需要比较紧挨的两个即可,不用每次比较两边),找到后再从后往前找第一个大于非逆序数i的数字j,这两个交换位置,即i这个位置还能继续往后迭代。需要的是一个大于他的数字j放到i,然后后面的转置即可(之前都是逆序,转为正序)

class Solution {
public:
void nextPermutation(vector<int> &num) {
int i, j, n = num.size();
for (i = n - 2; i >= 0; --i) {
if (num[i + 1] > num[i]) {
for (j = n - 1; j >= i; --j) {
if (num[j] > num[i]) break;
}
swap(num[i], num[j]);
reverse(num.begin() + i + 1, num.end());
return;
}
}
reverse(num.begin(), num.end());
}
};


Permutations II

对于有重复数字的情况,其实仅需要考虑重复的数字不要越过之前相同数字的位置。

从排列的角度来看,将有重复的数字摆好,其他的数字在其中插入,本质是重复数字不越位

def permuteUnique(self, nums):
ans = [[]]
for n in nums:
new_ans = []
for l in ans:
for i in xrange(len(l)+1):
new_ans.append(l[:i]+
+l[i:])
if i<len(l) and l[i]==n: break              #handles duplication
ans = new_ans
return ans


public class Solution {
public List<List<Integer>> permuteUnique(int[] nums) {
List<List<Integer>> res = new ArrayList<List<Integer>>();
if(nums==null || nums.length==0) return res;
boolean[] used = new boolean[nums.length];
List<Integer> list = new ArrayList<Integer>();
Arrays.sort(nums);
dfs(nums, used, list, res);
return res;
}

public void dfs(int[] nums, boolean[] used, List<Integer> list, List<List<Integer>> res){
if(list.size()==nums.length){
res.add(new ArrayList<Integer>(list));
return;
}
for(int i=0;i<nums.length;i++){
if(used[i]) continue;
if(i>0 &&nums[i-1]==nums[i] && !used[i-1]) continue;
used[i]=true;
list.add(nums[i]);
dfs(nums,used,list,res);
used[i]=false;
list.remove(list.size()-1);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: