Leetcode 47. Permutations II

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

Example:

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

这道题现在的水平只考虑学会用回溯来解, 当时对于回溯这个思路是很不清晰的 什么时候要传入一个start索引, 什么时候不用传。

现在清晰明白了。

根据这道题来总结回溯解题的思路,  首先就是要根据给定的数组来形成一个排列列表, 列表中的每个排列都是独一无二的。

那么1,1, 2 三个元素就需要分别当做第一个元素来进行排列。 所以在回溯当中的for循环我门不需要传start索引,三个元素当中的元素放入了列表后就对数组从0开始遍历将其他元素也跟着放进去即可。 放进去的时候要注意一个问题, 就是不能重复放入。

那么就得理解它为什么会重复, 什么时候会重复。 根据上面提的回溯思路 每个元素放进去后要对数组又完整的遍历一遍(包括已经放进去的元素), 而且数组本身又有值相等的元素。  那么什么时候会重复呢 举个栗子: 1(假设为A1),1(假设B1),2,  就是A1 B1  2, 这样以后又有B1 A1 2  又或者A1 A1 2, B1 B1 2这样4种重复的情况。 这样列举出来代码就知道怎么写了。

class Solution {
    public List<List<Integer>> permuteUnique(int[] nums) {
    List<List<Integer>> list = new ArrayList<>();
    Arrays.sort(nums);
    backtrack(list, new ArrayList<>(), nums, new boolean[nums.length]);
    return list;
}

private void backtrack(List<List<Integer>> list, List<Integer> tempList, int [] nums, boolean [] used){
    if(tempList.size() ==  nums.length) {
        list.add(new ArrayList<>(tempList));
    }
    
    for(int i = 0; i < nums.length; i++) {
// used[i]是防止 A1 A1 2 B1 B1 2这两种重复情况,   nums[i] == nums[i-1] && !used[i-1]是防止B1 A1 2
        if(used[i] || i > 0 && nums[i] == nums[i-1] && !used[i - 1]) continue;
        tempList.add(nums[i]);
        used[i] = true;
        backtrack(list, tempList, nums, used);
        used[i] = false;
        tempList.remove(tempList.size() - 1);
       
    }
}
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值