将数组分为两部分。需要更好的解决方

时间:2014-11-30 16:08:54

标签: python arrays algorithm optimization partitioning

给定一个1和0的数组,将数组分成若干部分,使得第一个数组中的1的数量等于另一个中的0的数量。 。打印发生此分区的索引。如果有很多这样的可能性,找到第一个这样的分区。

下面在python中给出了示例代码。它打印的答案是7.这意味着第一个数组直到a[7]。第二个数组从a[8]开始直到结束。

这个算法工作正常,但我认为复杂度是O(n ^ 2)。如果可能,我想要更好的解决方案。任何帮助都会很棒。

def findParts(arr):
    length=len(arr)
    count_ones = 0
    count_zeros = 0
    index=0

    for index in range(length-1):
        if arr[index] == 1:
            count_ones+=1
        for j in range(index+1, length-1):
            if arr[j] == 0:
                count_zeros+=1

    if (count_ones-count_zeros == 0):
        return index
    else:
        count_zeros=0;

a=[1,1,0,0,1,0,0,0,1,0,1,1,0,1,0,1,1]
print findParts(a)

2 个答案:

答案 0 :(得分:4)

以下是线性时间算法,并证明了解决方案的存在以及该解决方案是唯一可行的解​​决方案:

lst = [1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1]

index = 0
leftCount, rightCount = 0, lst.count(0)
while leftCount < rightCount:
    if lst[index] == 1:
        leftCount += 1
    else:
        rightCount -= 1
    index += 1

print(lst[:index], index, lst[index + 1:])

这将从索引0开始,左侧分区为空,在左侧分区0中计数为1。我们在O(n)中找到右侧分区中的0。

现在,我们迭代地将索引或分隔符向右移动。我们这样做,只要leftCount仍然低于rightCount。如果这发生了变化,我们就找到了解决方案(因为两个计数都是相同的)。当我们向右移动时,我们会查看list元素。如果它是1,我们在左侧计数中添加一个;如果是0,我们会从正确的计数中减去一个。最终,我们将达到两个计数相等的完美指数。

由于我们只是在每次迭代中更改一个计数,因此总会有这样的解决方案。而且,由于进一步迭代会使余额再次失效,这也证明只有单个解决方案。

至于时间复杂度,我们迭代列表一次以计算零,然后我们在移动边界时再次迭代它。所以这是O(n)。

答案 1 :(得分:1)

从分隔符位于中心元素开始,并计算数组左侧部分(#(1))的总数1和右侧部分的总数0( #(0))。

如果#(1) < #(0)将分隔符向右移动一个元素并相应地更新#(0)#(1)(基于前一个分隔符的值和新分隔符的值)。

如果#(1) > #(0)移动分隔符,则会向左移动一个元素并相应地更新#(0)#(1)

您会在O(n)找到分隔符。

您可以事先检查解决方案是否存在,以防止无限循环(如果没有解决方案,那么当数组全部为0时全部为1&#39; s。)

以下是代码:

import math

def findParts(arr):
    length = len(arr)
    index = int(math.ceil(length/2.0))
    count_ones = arr[:index+1].count(1)
    count_zeros = arr[index+1:].count(0)
    if count_ones == 0 or count_ones == length:
        return -1

    while count_ones != count_zeros:
        if count_ones < count_zeros:
            index+=1
            if arr[index] == 1:
                count_ones+=1
            else:
                count_zeros-=1
        else:
            if arr[index] == 1:
                count_ones-=1
            else:
                count_zeros+=1
            index-=1

    return index


a=[1,1,0,0,1,0,0,0,1,0,1,1,0,1,0,1,1]
print findParts(a)