Permutation 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].


11/3

这道题难点是怎么去掉重复的元素, 我采用的方法是对于num[i], 如果num[i-1] == num[i], 那么num[i]必须要在同样的元素之后才能插入, 比如

【1,2,3】

L【0】 = 【1】

L【1】 = 【1,2】【2,1】

L【2】=【1,2,3】【1,3,2】【3,1,2】【3,2,1】【2,3,1】【2,1,3】

而对于【1,2,2】

L【1】 是相同的,接下来在插入出现过的2的时候,

对于【1,2】, 只能插到2后头, 形成【1,2,2】

对于【2,1】, 只能形成【2,2,1】 和 【2,1,2】

就只有3个解

public class Solution {
    List<List<Integer>> ans;
    int len = 0;
    public List<List<Integer>> permuteUnique(int[] num) {
        Arrays.sort(num);
        ans = new ArrayList<List<Integer>>();
        len = num.length;
        permuteRec(num, new ArrayList<Integer>());
        return ans;
    }
    
    private void permuteRec(int[] num, List<Integer> prev){
        int now = prev.size(); // the next index to consider
        if(now == len){
            ans.add(prev);
            return;
        }else{
            if(now == 0 || num[now] > num[now-1]){
                // insert num[now] to all the possbile position
                int size = prev.size();
                for(int i=0; i<=size; i++){
                    List<Integer> copy = new ArrayList<Integer>(prev);
                    copy.add(i, num[now]);
                    permuteRec(num, copy);
                }
            }else{ // num[now] > num[now-1], only add after the previous same element
                int size = prev.size();
                int start = size-1;
                for(; start >= 0; start--){
                    if(prev.get(start) == num[now])     break;
                }
                // start > 0 has to hold
                for(int i=start+1; i<=size; i++){
                    List<Integer> copy = new ArrayList<Integer>(prev);
                    copy.add(i, num[now]);
                    permuteRec(num,copy);
                }
            }
            
        }
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值