zoukankan      html  css  js  c++  java
  • [LeetCode] 47. 全排列 II

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

    题目描述:

    给定一个可包含重复数字的序列,返回所有不重复的全排列。

    示例:

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

    思路:

    思路一: 库函数

    class Solution:
        def permuteUnique(self, nums: List[int]) -> List[List[int]]:
            return list({p for p in itertools.permutations(nums)})
    

    思路二: 回溯算法

    通过排序,来减少重复数组进入res


    关注我的知乎专栏,了解更多的解题技巧,共同进步!

    代码:

    class Solution:
        def permuteUnique(self, nums: List[int]) -> List[List[int]]:
            nums.sort()
            res = []
            visited = set()
            def backtrack(nums, tmp):
                if len(nums) == len(tmp):
                    res.append(tmp)
                    return
                for i in range(len(nums)):
                    if i in visited or (i > 0 and i - 1 not in visited and nums[i-1] == nums[i]):
                        continue
                    visited.add(i)
                    backtrack(nums, tmp + [nums[i]])
                    visited.remove(i)
            backtrack(nums, [])
            return res
    
    class Solution {
        public List<List<Integer>> permuteUnique(int[] nums) {
            List<List<Integer>> res = new ArrayList<>();
            Arrays.sort(nums);
            int[] visited = new int[nums.length];
            backtrack(res, nums, visited, new ArrayList<Integer>());
            return res;
    
        }
    
        private void backtrack(List<List<Integer>> res, int[] nums, int[] visited, ArrayList<Integer> tmp) {
            if (tmp.size() == nums.length) {
                res.add(new ArrayList<>(tmp));
                return;
            }
            for (int i = 0; i < nums.length; i++) {
                if (visited[i] == 1 || (i > 0 && visited[i - 1] == 0 && nums[i - 1] == nums[i])) continue;
                visited[i] = 1;
                tmp.add(nums[i]);
                backtrack(res, nums, visited, tmp);
                tmp.remove(tmp.size() - 1);
                visited[i] = 0;
            }
        }
    }
    

    类似题目还有:

    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
    
  • 相关阅读:
    提升树在回归方法中的应用
    前向分布算法
    提升树
    AdaBoost算法学习笔记
    统计学习方法-提升方法
    序列最小最优化算法
    mysql-profiling详解
    mysql,简单介绍一下索引
    MySQL Explain详解
    spring的事务传播行为
  • 原文地址:https://www.cnblogs.com/powercai/p/10870377.html
Copyright © 2011-2022 走看看