Write two functions:
subset_sums(nums: list[int]) -> list[int]: the sums of all2^nsubsets ofnums(chosen by position, so repeats are kept), sorted ascending. The empty subset contributes0.has_subset_sum(nums: list[int], target: int) -> bool: is there a subset ofnums(possibly empty) whose sum is exactlytarget?
subset_sums([1, 2, 4]) # [0, 1, 2, 3, 4, 5, 6, 7]
subset_sums([3, 3]) # [0, 3, 3, 6]
subset_sums([]) # [0]
has_subset_sum([5, -2, 9, 4], 7) # True (5 + -2 + 4)
has_subset_sum([5, -2, 9, 4], 1) # False
nums can have up to 36 elements with values up to 10^9 in size (so no DP over sums), and 2^36 subsets is far too many. That's the meet-in-the-middle setting: split nums into two halves, list the 2^18 subset sums of each half with subset_sums, and a subset of the whole list is just one subset from the left half plus one from the right. Put the right half's sums in a set and, for each left sum s, check whether target - s is in it.
Build subset_sums iteratively: start with [0], and for each number x, the new list is the old list plus x added to each old sum.
Constraints: 0 <= len(nums) <= 36 (at most 18 for direct calls to subset_sums), -10^9 <= nums[i], target <= 10^9.
Show hint
sums = [0]; for x in nums: sums += [s + x for s in sums], and has_subset_sum runs that on each half, then does set lookups.