LeetCode47 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,1,2],
  [1,2,1],
  [2,1,1]
]

解题思路:

这道题是46题的变形,大体思路还是用递归,区别在于这里数组包含了重复值。在这里,我的思路是建立一个map,键值对就是数组中的树和出现的次数。在往列表中添加的时候,会用键值对进行比较,如果使用的次数小于出现的次数,那么可以添加,反之则不能。代码如下:

public class Solution {
    public List<List<Integer>> permuteUnique(int[] nums) {
        int len = nums.length;
        Map<Integer,Integer> ans = new HashMap<Integer,Integer>();
        for(int i :nums){
            ans.put(i, ans.get(i)==null?1:ans.get(i)+1); //建一个键值对为数组中的数和出现次数的map
        }
        List<List<Integer>> res = new ArrayList();
        List<Integer> add = new ArrayList<Integer>();
        permuteRecursion(res, add,len, ans);
        return res;
    }

    private void permuteRecursion(List<List<Integer>> res, List<Integer> add,
            int len, Map<Integer, Integer> ans) {
        if(add.size()==len){
            List<Integer> tmp = new ArrayList<Integer>(add);
            res.add(tmp);
        }
        for(int i :ans.keySet()){//这里不用nums[]进行循环了,因为会使得添加的list有重复
            Map<Integer,Integer> map = new HashMap<Integer,Integer>();
            for(int m :add){ 
                map.put(m, map.get(m)==null?1:map.get(m)+1); //使用次数的
            }
            if(map.get(i)==null||map.get(i)<ans.get(i)){//使用次数与出现次数进行比较
                add.add(i);
                permuteRecursion(res, add,len, ans);
                add.remove(add.size()-1);
            }else{continue;}
        }
    }
}

重点说明:

1.我将nums数组转换成了键值对为数组中的数和出现次数的map。
2.循环使用map来完成,取代了nums[]。因为用nums[]循环的话,在list添加时会出现重复值。
3.在递归中,要建立一个map,用来记录当前list中存在的数和使用的次数。
4.将使用次数和出现次数进行比较,这里还要注意没用到当前数的情况,即:map.get(i)==null。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值