【问题标题】:Given a list of integers, split it into 2 list that return True if it is equal, else, return False (If it is impossible)给定一个整数列表,将其拆分为 2 个列表,如果相等则返回 True,否则返回 False(如果不可能)
【发布时间】:2021-03-17 15:58:43
【问题描述】:

和以前一样,我得到了一个字符串列表,我必须将该 ONE 列表拆分为两个列表,以检查是否可能有相等的总和。如果可能,返回数组 1 和数组 2。

以下代码适用于一组组合

例如。 myArr = [1, 2, 3, 4]

每次完整迭代都会执行以下操作 (targetSum = sum(myArr) / 2) #5

#1: PartialArr1 = [1] , PartialArr2 = [2,3,4] , 检查是否 Arr1 == targetSum

#1: PartialArr1 = [1, 2] , PartialArr2 = [3,4] , 检查是否 Arr1 == targetSum

#1: PartialArr1 = [1, 2, 3] , PartialArr2 = [4] , 检查是否 Arr1 == targetSum

#1: PartialArr1 = [1, 2, 3, 4] , PartialArr2 = [] , 检查是否 Arr1 == targetSum

虽然 #1 不返回任何 True 值,但将数字排列一次

#2: myArr = [2, 3, 4, 1]

#2: PartialArr1 = [2] , PartialArr2 = [3,4,1] , 检查是否 Arr1 == targetSum

#2: PartialArr1 = [2, 3] , PartialArr2 = [4,1] , 检查是否 Arr1 == targetSum #返回 PartialArr1, PartialArr2

def group(s):

    sumOfArr = sum(s)
    isPossible = sumOfArr%2

    if(isPossible == 0):
        #No remainder, possible to get a combination of two equal arrays
        targetSum = int(sumOfArr/2)

        partialArr1 = []
        partialArr2 = []
        i = 0
    
        while(targetSum != sum(partialArr1)):
            partialArr1.append(s[i])
            partialArr2 = s[i+1:]
        
            i+=1
        
            if(i == len(s)-1) or (sum(partialArr1) > targetSum):
                partialArr1 = []
                partialArr2 = []
                i = 0
                s = s[1:] + s[:1]

        return partialArr1,partialArr2
    else:
        #Not possible, return None, None
        return None, None

虽然我的解决方案适用于大多数排列组,但不适用于以下情况:

#The following works with my code ->
#s = [135, 129, 141, 121, 105, 109, 105, 147]
#s = [-14, 3, 4, 13, -1, -5, 0, 5, -10, 8, -4, 10, -12, 11, 9, 12, -6, -11, -9, -8]
#s= [-1, 1, 4, 2, 8, 0]
#s = [10, 2,2,10, 2, 2, 2,10]


#SOLUTION SHOULD RETURN THE FOLLOWING
#s1 = [6, 10, 6, 10], sum(s1) = 32
#s2 = [7, -3, 1, -4, 2, 2, 7, -3, 2, 4, 0, 7, 6, -2, -4, 10], sum(s1) = 32


s = [7, -3, 6, 1, 10, -4, 2, 2, 6, 7, -3, 2, 4, 0, 7, 6, -2, 10, -4, 10]

group(s) #This does not work because it does not permutate all possible ways of len(s)^2 ways. Thus I am stucked at this point of time

任何帮助将不胜感激!谢谢!!

【问题讨论】:

  • 您的 while 循环仅测试数组的一个拆分,而问题(和示例)表明您需要测试许多(如果不是全部)组合。所以解决方案将取决于上下文(这个问题是关于暴力算法的讲座的一部分,使用组合吗?关于动态编程?还是可以接受贪婪的解决方案?)
  • 嗨,我使用的方法没有要求,但是我已经编辑了我的答案,请看一下,现在我被 [1,2,3, 4], [2,3,4,1], [3,4,1,2], [4,3,2,1]

标签: python


【解决方案1】:

据我了解,您需要查看您的数组是否可以分为2个相等的数组并返回True,否则返回False,您不需要它划分的数组,只需事实上,它可以被分割。

如果你的数组可以分成两个相等的数组,那么它的一些元素的总和应该是你数组总和的一半。

例如:

[5,3,5,2,10,1]

这个数组的和是 26。如果它的一些元素可以等于 13,那么它可以被分成 2 个相等数组的数组,因为其余元素的和也会为 13。 example : [10,3] and [5,5,2,1],因此当您发现数组元素的组合等于整个数组总和的一半时,您会返回 True。同样,具有奇数和的数组也自动不可分割为 2 个相等的数组。注意:搜索所有组合具有很高的复杂性,并且对于大型列表会很慢。

这正是我正在做的,使用 itertools 得到总和为数组总和一半的组合,如果有组合,那么它可以分成 2 个相等的数组,测试它:

import itertools
numbers = [135, 129, 141, 121, 105, 109, 105, 147]


if((sum(numbers)%2)!=0):
    print(False)
else:
    result = [seq for i in range(len(numbers), 0, -1) for seq in itertools.combinations(numbers, i) if sum(seq) == (sum(numbers)//2)]
    if len(result)>1:
        print(True)
    else:
        print(False)

【讨论】:

  • 感谢您的回答!但是,遗憾的是,我不允许为这个问题导入任何库......因此我很困惑如何在不导入 ang 库的情况下做到这一点
  • 我在没有库的情况下添加了第二个答案,只是一个递归函数来检查所有组合并在找到一个当对其数字求和时等于数组/2 的所有数字之和时返回 true,它是更快更好,完美运行,看看吧。
  • 谢谢,我已经尝试过了,但我正在尝试更改不在嵌套函数中运行的代码〜但是,我更改的代码不允许我当我找到答案时,跳出循环。如果为真,我也试图返回数组
  • 嗨 Elyes,我已经更新了我的关键答案 + 发布,您是否可以快速查看一下是否有任何解决方案,因为目前我面临一些问题。我会在我的主要 qns 中注意到这个问题
【解决方案2】:

这是你需要的函数,当数组可以分成两个相等的数组时返回True,如果不能,则返回False,不使用任何库:

def search(numbers):
    target = sum(numbers)/2
    def subset_sum(numbers, target, partial=[]):
        s = sum(partial)

        if s == target:
            print(5/0)
        if s >= target:
            return 

        for i in range(len(numbers)):
            n = numbers[i]
            remaining = numbers[i + 1:]
            subset_sum(remaining, target, partial + [n])
    try:
        subset_sum(numbers, target)
        return False

    except:
        return True

numbers = [135, 129, 141, 121, 105, 109, 105, 147]
print(search(numbers))

【讨论】:

    猜你喜欢
    • 2021-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-23
    • 2020-03-28
    • 1970-01-01
    • 2018-03-23
    • 2018-10-22
    相关资源
    最近更新 更多