LeetCode:47. Permutations II

Given a collection of numbers, nums, that might contain duplicates, return all possible unique permutations in any order.

Example 1:

Input: nums = [1,1,2]
Output:
[[1,1,2],
 [1,2,1],
 [2,1,1]]

Example 2:

Input: nums = [1,2,3]
Output: [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

Constraints:

  • 1 <= nums.length <= 8
  • -10 <= nums[i] <= 10

 

解法:

这道题与46题的唯一区别就是给出的数组里有重复的数字,这样一来如果还按照上一题的解法去做,那么肯定会生成出重复的排列。

其实我们可以换一个思路去解决全排列生成问题。比如有数组[1,1,2],那么可以把这三个数字的全排列想象成是一个具有三个空的slot,然后把[1,1,2]想象成一个装了3个球的袋子(两个红球,一个蓝球),那么寻找这三个数的一个排列的过程就是从袋子中每次取出一个球,然后依次放进这三个空的slot中的过程。那么如果我们随机的从袋子里去取三个球,那么很有可能会凑巧的连续几次都取出同一个颜色的球,那么就会出现生成出重复排列的情况。那么有啥办法能避免这种情况呢?我们可以先把这3个球分成两组,两个红球为一组,一个蓝球为一组,然后每次我们都从其中的一组里取一个球,直到把所有空位填满为止。

public static List<List<Integer>> permuteUnique(int[] num) {
		List<List<Integer>> ans = new ArrayList<List<Integer>>();
		Map<Integer, Integer> groups = new HashMap<>();
		for (int n : num) {
			groups.putIfAbsent(n, 0) ;
			groups.put(n, groups.get(n) + 1);
			
		}
		permutation(num.length, groups, new LinkedList<>(), ans);
		return ans;
	}

	public static void permutation(int maxLen, Map<Integer, Integer> groups, LinkedList<Integer> currList, List<List<Integer>> ans){
		if(currList.size() == maxLen) {
			ans.add(new ArrayList(currList)) ;
			return ;
		}
		
		for(Entry<Integer, Integer> entry : groups.entrySet()) {
			int num = entry.getKey() ;
			int count = entry.getValue() ;
			if(count == 0) {
				continue ;
			}
			
			currList.add(num);
			groups.put(num, count - 1) ;
			permutation(maxLen, groups, currList, ans);
			groups.put(num, count) ;
			currList.removeLast() ;
			
		}
		
	}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yexianyi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值