HackerRank最大子阵列

时间:2015-09-25 15:48:21

标签: python algorithm kadanes-algorithm

所以我试图通过HackerRank上的动态编程轨道。

问题提示如下。

给定N个元素的数组A = {a1,a2,...,aN},找到最大可能的总和

连续子阵列非连续(不一定是连续的)子阵列。 不应考虑空子阵列/子序列。

输入格式

输入的第一行有一个整数 T T 案例随之而来。 每个测试用例都以整数 N 开头。在下一行中, N 整数表示数组 A 的元素。

约束上:
    

您考虑的子阵列和子序列应至少包含一个元素。

输出格式

两个,空格分隔,整数表示最大的连续和非连续子阵列。应该选择至少一个整数并将其放入子数组中(在所有元素都为负数的情况下可能需要这样做。)

示例输入

2 
4 
1 2 3 4
6
2 -1 2 3 4 -5

示例输出

10 10
10 11

解释
在第一种情况下: 连续和非连续元素的最大总和是所有元素的总和(因为它们都是正数)。

在第二种情况下: [2 -1 2 3 4] - >这形成具有最大总和的连续子阵列。 对于不一定连续的元素组的最大总和,只需添加所有正元素。

<小时/> 我对此的解决方案是

def dp2(L):
    max_so_far = max_ending_here = -2**31 # contig logic works
    non_contig = [L[0]] # accounting for negative arrays

    for i in xrange(len(L[0::])):
        max_ending_here = max(L[i], max_ending_here + L[i])        
        max_so_far = max(max_so_far, max_ending_here) 
        # non-contiguous logic
        if i != 0:
            non_contig.append(max(non_contig[-1], non_contig[-1] + L[i]))   
    return map(str, (max_so_far, non_contig[-1]))

if __name__ == '__main__':
    test_cases = int(raw_input())
    for i in xrange(test_cases):
        arr_length = int(raw_input())
        array = [int(i) for i in raw_input().split()] 

        print ' '.join(dp2(array))

所以上面的代码只传递了一个测试用例。这是非常大的,因此我决定将所有测试用例上传到unittest并在我的本地环境中运行以查看发生了什么。

This

.F..
======================================================================
FAIL: test_answers_against_test_case2_outputs (__main__.TestCase2)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test_max_subarray.py", line 52, in test_answers_against_test_case2_outputs
    self.assertEqual(result, self.outputs[idx])
AssertionError: Lists differ: ['2617065', '172073086'] != [u'2617065', u'172083036']

First differing element 1:
172073086
172083036

- ['2617065', '172073086']
?                  ^  ^

+ [u'2617065', u'172083036']
?  +           +     ^  ^


----------------------------------------------------------------------
Ran 4 tests in 0.951s

FAILED (failures=1)

对于dp函数吐出的非连续答案,有两个数字是不正确的。这可能是从int转换为字符串的问题吗?

我意识到我正在将unicode与python字符串进行比较,但它似乎并不重要,因为我已经尝试了相反的方式,所以我不认为这是问题,但我可能是错的。

1 个答案:

答案 0 :(得分:1)

我知道我哪里出错了。对于非连续逻辑,我完全忘记了我可以简单地将当前总和设置为0并且只尝试将正整数添加到该逻辑中。

如果给定数组中的所有整数都是负数,那么只需获取最大值并将其作为最大总和返回。

工作代码。

def dp(L):
    max_so_far = max_ending_here = -2**31
    c_sum = 0
    max_neg = -2**31

    for i in xrange(len(L)):
        max_ending_here = max(L[i], max_ending_here + L[i])        
        max_so_far = max(max_so_far, max_ending_here)

        if L[i] > 0:
            c_sum += L[i] 
        else:
            if L[i] > max_neg:
                max_neg = L[i]
    if c_sum == 0: # All values were negative so just pick the largest
        c_sum = max_neg
    return map(str, (max_so_far, c_sum))

if __name__ == '__main__':
    test_cases = int(raw_input())
    for i in xrange(test_cases):
        arr_length = int(raw_input())
        array = [int(i) for i in raw_input().split()]

        print ' '.join(dp(array))

我没有在for循环之外使用python的最大函数,而是选择在循环中跟踪这些函数以尝试使运行时保持接近O(n)。