所以我试图通过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并在我的本地环境中运行以查看发生了什么。
.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字符串进行比较,但它似乎并不重要,因为我已经尝试了相反的方式,所以我不认为这是问题,但我可能是错的。
答案 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)。