defcanPartition(self, nums) -> bool: # 计算总价值 c = sum(nums) # 奇数直接排除 if c % 2 != 0: returnFalse c = c // 2 w = [False] * (c + 1) # 第0个位置设置为true,表示当元素出现的时候让w[i-num]为True,也就是w[i]为True w[0] = True for num in nums: for i in range(c, num - 1, -1): w[i] = w[i] or w[i - num]
classSolution: defpermute(self, nums: List[int]) -> List[List[int]]: defcore(nums,tmp): if nums==[]: result.append(tmp) return for num in nums: s = nums[::] s.remove(num) core(s,tmp+[num]) result = [] core(nums,[]) return result
拓展:含重复数组的全排列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
defpermuteUnique(self, nums: List[int]) -> List[List[int]]: defcore(nums,tmp): if nums==[]: if tmp notin result: result.append(tmp) return for num in nums: s = nums[::] s.remove(num) core(s,tmp+[num]) result = [] nums.sort() core(nums,[]) return result
3.划分为k个相等的子集
给定一个整数数组 nums 和一个正整数 k,找出是否有可能把这个数组分成 k 个非空子集,其总和都相等。
defcanPartitionKSubsets(self, nums: List[int], k: int) -> bool: if k == 1: returnTrue #如果不能被k整除,那么直接无解 sum_num = sum(nums) if sum_num % k != 0: returnFalse avg = sum_num // k nums.sort(reverse=True) n = len(nums) if n < k :returnFalse visited = set() #标志位,标志哪个位置已经被使用过了
defdfs(k,tmp_sum,loc): #当选用的几个数之和等于目标值,那么k减一,再找下一个子集 if tmp_sum == avg: return dfs(k-1,0,0) #如果k==1,由于上面已经验证过可以被k整除,因此一定成立 if k == 1: returnTrue for i in range(loc,n): if i notin visited and nums[i] + tmp_sum <= avg: visited.add(i) if dfs(k,tmp_sum+nums[i],i+1): returnTrue visited.remove(i) returnFalse return dfs(k,0,0)