有没有一种方法可以打印列表中的2个均和子列表?

时间:2020-04-27 19:21:23

标签: python algorithm recursion dynamic-programming subset-sum

因此,如果有2个子列表具有相同的总和(总和的1/2),那么我在这里有此代码可以正常工作并返回True 了解有关Partition Equal Subset Sum

的更多信息

示例:

s = Solution()
print(s.canPartition([3,10,9,2]))
# output [3, 9] , [10, 2]

我的代码对索引进行迭代,并且每次迭代都以2种方式进行拆分-第一种方式是将值加到sum ..第二种方式是继续进行而不添加值。 如果其中一种方法返回True,则表示已找到解决方案。

时间复杂度应为2 ^ n,但由于动态编程,它已降低为O(n)

现在我试图找出的问题是如何回溯“真实根”并打印属于根的所有项目(希望是总金额的一半)

我以“真根”的意思是某种方式,当我返回“第一真”时(这意味着我已经找到了总和),因此我已经有了这些物品。 例子:

[3,10,9,2]
# output [3, 9] , [10, 2]

Tree of recursive:

          []
         /   \
       [3]    []
      /   \     \
 [3,10]   [3]    [] 
   /      /        \
        [3,9] # THE Root returing firt true 

代码:

class Solution:
    def canPartition(self, nums: List[int]) -> bool:
        def helper(s1, s2, i, memo):

            # recursion

            hashed = (s1 + s2)
            if hashed in memo.keys():
                return memo[hashed]

            if s1 == s2:    # we have 2 groups of sums that sums total
                return True

            if s1 > s2: # we have too big group
                return False

            if i == len(nums):  # the end
                return s1 == s2

            # 2 options : move to next index with/witohut counting index
            memo[hashed] = helper(s1 + nums[i], s2, i + 1, memo) or helper(s1, s2, i + 1, memo)

            return memo[hashed]

        # begin

        s = sum(nums)   # sum
        memo = {}   # dynamic programing

        if s % 2 == 0:  # odd sum can't be divided equally
            return helper(0, s // 2, 0, memo)

        return False

示例,用于更好地理解我的期望输出:

s = Solution()
print(s.canPartition([3,10,9,2]))
# output [3, 9] , [10, 2]

1 个答案:

答案 0 :(得分:1)

有用的提示

您的helper函数将返回TrueFalse。在返回True之前,请尝试打印您在该递归中考虑的最后一个元素nums[i]

另一个提示

helper中,您要进行两个递归调用。

  1. helper(s1 + nums[i], s2, i + 1, memo)

  2. helper(s1, s2, i + 1, memo)

如果步骤1的结果为True,则意味着您将nums[i]保留在总和中。您需要拆分该OR语句才能找到答案。拆分时,如果步骤1为True,则无需运行步骤2。