问题
My code is not showing the shortest subset eg [7] or it is not reading all the subsets, [7], [3,4] to return the shortest subset. Can explain why only 1 set of result is return and how should I modify it to show all subset? Thanks
Image of Code that i wanted to follow as below
def howsum(targetsum,numbers,combo=None):
if combo == None:
combo = list()
if targetsum == 0: return [ ]
if targetsum < 0: return None
shortcombo = None
for number in numbers:
remainder = targetsum - number
combo = howsum(remainder,numbers,combo)
if combo != None:
combo.append(number)
if shortcombo == None or len(shortcombo) > len(combo):
shortcombo = combo
return shortcombo
return shortcombo
print(howsum(7,[4,3,7]))
回答1:
Wrote code that closely matches the original JavaScript.
Although JavaScript names will work, I refactored function and variable names to agree with Python style, namely:
- Function names should be lowercase, with words separated by underscores as necessary to improve readability.
- Variable names follow the same convention as function names.
Code
def best_sum(target_sum, numbers):
if target_sum == 0: return []
if target_sum < 0: return None
shortest_combination = None
for num in numbers:
remainder = target_sum - num
remainder_combination = best_sum(remainder, numbers)
if remainder_combination != None:
combination = [*remainder_combination, num] # Python * equivalent to JavaSscript ...
if shortest_combination == None or len(combination) < len(shortest_combination):
shortest_combination = combination
return shortest_combination
Test
print(bestSum(7, [3, 4, 7])) # Output: [7]
Using Memoization (i.e. caching)
def best_sum(target_sum, numbers, memo = None):
if memo is None:
memo = {0:[]}
if target_sum < 0:
return None
if target_sum in memo:
return memo[target_sum]
shortest_combination = None
for num in numbers:
remainder = target_sum - num
remainder_combination = best_sum(remainder, numbers, memo)
if remainder_combination != None:
combination = [*remainder_combination, num] # Python * equivalent to JavaSscript ...
if shortest_combination == None or len(combination) < len(shortest_combination):
shortest_combination = combination
memo[target_sum] = shortest_combination
return memo[target_sum]
print(best_sum(7, [3, 4, 7])) # Output: 7
# Following very slow on non-memoized version
print(best_sum(100,[10,1,25])) # Output: [25, 25, 25, 25]
回答2:
I am not sure about this but while defining a function in python and giving 2 sets of codes it is not actually performing the second set of the code when calling out the function. I got the same problem with some other project. And I got no answers but saying I did some wrong in the code!!!
回答3:
Added memoization, however with 1 inside sets of num. the results gone haywire.
def best_sum(target_sum, numbers,memo=None):
if memo == None:
memo = dict()
if target_sum in memo:
return memo[target_sum]
if target_sum == 0: return []
if target_sum < 0: return None
shortest_combination = None
for num in numbers:
remainder = target_sum - num
remainder_combination = best_sum(remainder, numbers,memo)
if remainder_combination != None:
remainder_combination.append(num)
combination = remainder_combination
if shortest_combination == None or len(combination) < len(shortest_combination):
shortest_combination = combination
memo[target_sum] = shortest_combination
return shortest_combination
print(best_sum(100,[5,1,25]))
This code by answer posted by DarylG works. By changing the .append
to [*list,var]
However I dont understand why is the result different between function append and *
def best_sum(target_sum, numbers,memo=None):
if memo == None:
memo = dict()
if target_sum in memo:
return memo[target_sum]
if target_sum == 0: return []
if target_sum < 0: return None
shortest_combination = None
for num in numbers:
remainder = target_sum - num
remainder_combination = best_sum(remainder, numbers,memo)
if remainder_combination != None:
combination = [*remainder_combination,num] #this line from append to *
if shortest_combination == None or len(combination) < len(shortest_combination):
shortest_combination = combination
memo[target_sum] = shortest_combination
return shortest_combination
print(best_sum(100,[5,1,25]))
回答4:
I checked out your code. What I felt missing was
Incorrect placement of return and storing the values inside of combo (set instead of list).
def howsum(targetsum,numbers,combo=None): if combo == None: combo = set() if targetsum == 0: return [ ] if targetsum < 0: return None for idx,number in enumerate(numbers): remainder = targetsum - number if howsum(remainder,numbers[idx:],combo) != None: combo.add(number) else: return combo return None
print(howsum(7,[7,3,4,2,5]))
Hope this helps. While this gives you a solution I would recommend using a different way to solve such issues (twoSum solutions) or two pointer approach with O(n).
来源:https://stackoverflow.com/questions/65386932/python-recursive-function-how-to-return-all-subsets-of-targetsum