leetcode 47:全排列ii

leetcode 47:全排列II

给定一个可包含重复数字的序列 nums按任意顺序 返回所有不重复的全排列。

示例 1:

输入:nums = [1,1,2]
输出:
[[1,1,2],
 [1,2,1],
 [2,1,1]]

示例 2:

输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

提示:

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

Related Topics

数组

回溯

回溯

因为-10 <= nums[i] <= 10,所以可以修改原数组的值为flag进行标记,减少空间复杂度。

遍历整个数组,每一个值都可能在这个位置上。(没有被标记的,重复的值选取一个)

  1. 如果这个值没有被标记过,而且没有在这个位置被选取过(注意第一个值是没有前面的值
  2. 保存这个值,然后添加到list,并对这个位置进行标记,继续递归。
  3. 回溯这个值和list。
class Solution {
    List<List<Integer>> lists = new ArrayList<>();
    List<Integer> list = new ArrayList<>();
    private int flag = -20;
    public List<List<Integer>> permuteUnique(int[] nums) {
        Arrays.sort(nums);
        dfs(nums);
        return lists;
    }
    public void dfs(int[] nums){
        //找到排列
        if(list.size() == nums.length){
            lists.add(new ArrayList<>(list));
            return;
        }
        //遍历这个数组 找到合适的数放入进行递归

        for(int i = 0 ; i < nums.length;i++){
            //1. 这个数不能被选取过
            //2. 这个数不能等于前面的值(因为已经排序过 不能选取重复的值)
            if(nums[i] != flag &&(i == 0 || nums[i] != nums[i-1])){
                //利用原数组将选取的值修改成flag标记
                int temp = nums[i];
                nums[i] = flag;
                list.add(temp);
                dfs(nums);
                //返回时进行回溯
                list.remove(list.size()-1);
                nums[i] = temp;
            }
        }
    }
}
解答成功:
			执行耗时:1 ms,击败了99.78%Java用户
			内存消耗:42.3 MB,击败了11.73%Java用户
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值