• [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
    

  • 相关阅读:
    关于测试开发及其他——写在离职之前
    牛腩新闻发布系统——初探CSS
    牛腩新闻发布系统——后台前台整合技术
    Android Audio Focus的应用(requestAudioFocus)
    正则表达式详解
    牛腩新闻发布系统——初探JQuery,AJAX
    牛腩新闻发布系统——初探Javascript
    进入中文维基百科的方法
    *args 和**kwargs 的溯源
    mathematica9激活
  • 原文地址:https://www.cnblogs.com/powercai/p/11027834.html
Copyright © 2020-2023  润新知