698. Partition to K Equal Sum Subsets - cocoder39/coco39_LC GitHub Wiki

698. Partition to K Equal Sum Subsets

Option 1 (Preferred)

option 1 is consistent with how to solve other similar problems

class Solution:
    def canPartitionKSubsets(self, nums: List[int], k: int) -> bool:
        n = len(nums)
        list_sum = sum(nums)
        if list_sum % k != 0:
            return False
                
        target_sum = list_sum // k
        nums.sort(reverse = True) 
        sub_sums = [0] * k
        
        def helper(cur_idx):
            if cur_idx == n:
                return True
                    
            seen = set()
            for i in range(k):
                if sub_sums[i] + nums[cur_idx] <= target_sum:
                    if sub_sums[i] not in seen:
                        seen.add(sub_sums[i])
                        sub_sums[i] += nums[cur_idx]
                        if helper(cur_idx+1):
                            return True
                        sub_sums[i] -= nums[cur_idx]

            return False
                    
        return helper(0) 

Option 2

  • using start_idx to avoid processing a number again in the same subset
  • using visited to avoid processing a number that has been included into another subset

a rough upper bound of time complexity: it takes O(2^n) time complexity to build all 2^n potential first subsets, and it will build k levels in total so total time complexity is O(2^kn)

class Solution:
    def canPartitionKSubsets(self, nums: List[int], k: int) -> bool:
        n = len(nums)
        list_sum = sum(nums)
        if list_sum % k != 0:
            return False
                
        target_sum = list_sum // k
        nums.sort() 
        visited = [False] * n
        for i in range(n-1, -1, -1):
            if nums[i] > target_sum:
                return False
            if nums[i] == target_sum:
                visited[i] = True
                k -= 1
            if nums[i] < target_sum:
                break
        
        def helper(start_idx, visited, subset_sum, count):
            if count == 0:
                return True
                    
            for i in range(start_idx, len(nums)):
                if not visited[i]:
                    visited[i] = True
                    if subset_sum + nums[i] < target_sum and helper(i+1, visited, subset_sum + nums[i], count):
                        return True
                    elif subset_sum + nums[i] == target_sum and helper(0, visited, 0, count - 1):
                        return True
                    visited[i] = False
                    
            return False
                    
        return helper(0, visited, 0, k)