zoukankan      html  css  js  c++  java
  • [LeetCode] 90. 子集 II

    题目链接 : https://leetcode-cn.com/problems/subsets-ii/

    题目描述:

    给定一个可能包含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。

    说明:解集不能包含重复的子集。

    示例:

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

    思路:

    思路一:递归

    思路二:迭代

    直接看代码

    代码:

    思路一:

    class Solution:
        def subsetsWithDup(self, nums: List[int]) -> List[List[int]]:
            res = []
            n = len(nums)
            nums.sort()
            def helper(idx, tmp):
                res.append(tmp)
                for i in range(idx, n):
                    if i > idx and nums[i] == nums[i-1]:
                        continue
                    helper(i+1, tmp + [nums[i]])
            helper(0, [])
            return res
    

    java

    class Solution {
        public List<List<Integer>> subsetsWithDup(int[] nums) {
    
            List<List<Integer>> res = new ArrayList<>();
            if (nums == null || nums.length == 0) return res;
            Arrays.sort(nums);
            backtrack(0, nums, res, new ArrayList<>());
            return res;
    
    
        }
    
        public void backtrack(int idx, int[] nums, List<List<Integer>> res, List<Integer> tmp_list) {
            res.add(new ArrayList<>(tmp_list));
            for (int i = idx; i < nums.length; i++) {
                if (i > idx && nums[i - 1] == nums[i]) continue;
                tmp_list.add(nums[i]);
                backtrack(i + 1, nums, res, tmp_list);
                tmp_list.remove(tmp_list.size() - 1);
            }
        }
    }
    

    思路二:

    class Solution:
        def subsetsWithDup(self, nums: List[int]) -> List[List[int]]:
            if not nums: return []
            nums.sort()
            res = [[]]
            cur = []
            for i in range(len(nums)):
                if i > 0 and nums[i - 1] == nums[i]:
                    cur = [tmp + [nums[i]] for tmp in cur]
                else:
                    cur = [tmp + [nums[i]] for tmp in res]
                res += cur
            return res
    

    类似题目还有:

    39.组合总和

    40. 组合总和 II

    46. 全排列

    47. 全排列 II

    78. 子集

    90. 子集 II

    这类题目都是同一类型的,用回溯算法!

    其实回溯算法关键在于:不合适就退回上一步

    然后通过约束条件, 减少时间复杂度.

    大家可以从下面的解法找出一点感觉!

    78. 子集

    class Solution:
    	def subsets(self, nums):		
            if not nums:
    			return []
    		res = []
    		n = len(nums)
    
    		def helper(idx, temp_list):
    			res.append(temp_list)
    			for i in range(idx, n):
    				helper(i + 1, temp_list + [nums[i]])
    
    		helper(0, [])
    		return res
    

    90. 子集 II

    class Solution(object):
        def subsetsWithDup(self, nums):
            """
            :type nums: List[int]
            :rtype: List[List[int]]
            """
            if not nums:
                return []
            n = len(nums)
            res = []
            nums.sort()
    		# 思路1
            def helper1(idx, n, temp_list):
                if temp_list not in res:
                    res.append(temp_list)
                for i in range(idx, n):
                    helper1(i + 1, n, temp_list + [nums[i]])
    		# 思路2
            def helper2(idx, n, temp_list):
                res.append(temp_list)
                for i in range(idx, n):
                    if i > idx and  nums[i] == nums[i - 1]:
                        continue
                    helper2(i + 1, n, temp_list + [nums[i]])
    
            helper2(0, n, [])
            return res
    

    46. 全排列

    class Solution(object):
        def permute(self, nums):
            """
            :type nums: List[int]
            :rtype: List[List[int]]
            """
            if not nums:
                return
            res = []
            n = len(nums)
            visited = [0] * n
            def helper1(temp_list,length):
                if length == n:
                    res.append(temp_list)
                for i in range(n):
                    if visited[i] :
                        continue
                    visited[i] = 1
                    helper1(temp_list+[nums[i]],length+1)
                    visited[i] = 0
            def helper2(nums,temp_list,length):
                if length == n:
                    res.append(temp_list)
                for i in range(len(nums)):
                    helper2(nums[:i]+nums[i+1:],temp_list+[nums[i]],length+1)
            helper1([],0)
            return res
    

    47. 全排列 II

    class Solution(object):
        def permuteUnique(self, nums):
            """
            :type nums: List[int]
            :rtype: List[List[int]]
            """
            if not nums:
    			return []
    		nums.sort()
    		n = len(nums)
    		visited = [0] * n
    		res = []
    
    		def helper1(temp_list, length):
    			# if length == n and temp_list not in res:
    			# 	res.append(temp_list)
    			if length == n:
    				res.append(temp_list)
    			for i in range(n):
    				if visited[i] or (i > 0 and nums[i] == nums[i - 1] and not visited[i - 1]):
    					continue
    				visited[i] = 1
    				helper1(temp_list + [nums[i]], length + 1)
    				visited[i] = 0
    
    		def helper2(nums, temp_list, length):
    			if length == n and temp_list not in res:
    				res.append(temp_list)
    			for i in range(len(nums)):
    				helper2(nums[:i] + nums[i + 1:], temp_list + [nums[i]], length + 1)
    
    		helper1([],0)
    		# helper2(nums, [], 0)
    		return res
    

    39.组合总和

    class Solution(object):
        def combinationSum(self, candidates, target):
            """
            :type candidates: List[int]
            :type target: int
            :rtype: List[List[int]]
            """
            if not candidates:
                return []
            if min(candidates) > target:
                return []
            candidates.sort()
            res = []
    
            def helper(candidates, target, temp_list):
                if target == 0:
                    res.append(temp_list)
                if target < 0:
                    return
                for i in range(len(candidates)):
                    if candidates[i] > target:
                        break
                    helper(candidates[i:], target - candidates[i], temp_list + [candidates[i]])
            helper(candidates,target,[])
            return res
    

    40. 组合总和 II

    class Solution:
        def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
            if not candidates:
                return []
            candidates.sort()
            n = len(candidates)
            res = []
            
            def backtrack(i, tmp_sum, tmp_list):
                if tmp_sum == target:
                    res.append(tmp_list)
                    return 
                for j in range(i, n):
                    if tmp_sum + candidates[j]  > target : break
                    if j > i and candidates[j] == candidates[j-1]:continue
                    backtrack(j + 1, tmp_sum + candidates[j], tmp_list + [candidates[j]])
            backtrack(0, 0, [])    
            return res
    

  • 相关阅读:
    通讯录封装实现
    简单通讯录的实现 main..h .m文件全部
    iOS 开发 OC编程 字典和集合 排序方法
    iOS 开发 OC编程 数组冒泡排序.图书管理
    iOS 开发 OC编程 属性和字符串练习
    iOS 开发 OC编程 属性和字符串
    iOS 开发 OC编程 便利构造器以及初始化方法
    iOS 开发 OC编程 方法的书写
    IOS 开发 OC编程 类和对象
    iOS 开发 c语言阶段考试题
  • 原文地址:https://www.cnblogs.com/powercai/p/11027834.html
Copyright © 2011-2022 走看看