【牛客網刷題】一次難忘的編程教訓


昨天刷這樣一道編程題:

--------------------------------------------------------------------------------------------------

求連續子數組的最大和。

一個非空整數數組,選擇其中的兩個位置,使得兩個位置之間的數和最大。
如果最大的和為正數,則輸出這個數;如果最大的和為負數或0,則輸出0

--------------------------------------------------------------------------------------------------

 看到題目后,我的第一反應:“可以根據積分原理來解決,先將數組從左到右進行累加,根據累加數組的最小值、最大值來計算連續子數組的最大和”。

想象中,累加數組的折線圖大約是這個樣子:

“很顯然,連續子數組和的最大值為:累加數組的最大值與最小值之差。”

“如果累加數組的全局最大值在最小值左邊怎么辦?”

“那就找它的局部最大值、最小值,再比較多個局部的結果,取最大值。”

“如何找局部最大值、最小值?”

“把累加數組切分為兩部分,迭代計算。”

 

頭腦里這么想着,手指頭也跟着活動起來了,反正這就和“累加數組”杠上了。

寫完后提交代碼試運行,部分case不通過。然后修修補補,終於提交通過了。

代碼如下:

def find_max_sublist_sum(a_list):
 
    # 空list直接返回結果0
    if len(a_list) == 0:
        return 0
 
    # 去除list前面連續的負整數,生成新的new_list;如果list全部元素為負,則返回結果0
    indx = 0
    for x in a_list:
        if x > 0:
            break
        else:
            indx += 1
    if indx < len(a_list):
        new_list = a_list[indx:]
    else:
        return 0
 
     # 從前往后,計算new_list元素的累積和,生成accumulate_list
    accumulate = 0
    accumulate_list = []
    for x in new_list:
        accumulate += x
        accumulate_list.append(accumulate)
 
    # 找出累積和列表最大值、最小值對應的index
    index_min = accumulate_list.index(min(accumulate_list))
    index_max = accumulate_list.index(max(accumulate_list))
 
    # 根據累積和列表的最大值、最小值位置進行分類計算
    if index_min < index_max:   # 最小值在最大值左邊,取最小值到最大值區間內增量
        return max(accumulate_list) - min(min(accumulate_list), 0)
    elif index_min == index_max == 0:   # 最小值、最大值均 index == 1,說明列表只有一個正數
        return accumulate_list[0]
    else:   # 將列表分成2部分,遞歸處理
        list1 = new_list[:index_max+1]
        list2 = new_list[index_max+1:]
        return max(find_max_sublist_sum(list1), find_max_sublist_sum(list2))
 
 
if __name__ == '__main__':
    import sys
    for line in sys.stdin:
        testlist = line.split(',')
        testlist = [int(testlist[i]) for i in range(len(testlist))]
        print(find_max_sublist_sum(testlist))

  自我感覺,這個解法有些復雜,但是也沒認真去想其他的辦法。

 

今天再回過來看時,看到@牛客692333551號貼出來的解法,我恍然大悟。

@牛客692333551號解法如下:

x = [int(i) for i in input().split(',')]
res = 0
d = max(0, x[0])
res = max(res, d)
for i in range(1, len(x)):
    d = max(d + x[i], 0)
res = max(res, d)
print(res)

  

原來自己的方法太蠢、太丑了!不忍直視!

 

為什么自己如此堅決地捍衛自己的“第一反應”,寧可絞盡腦汁去修修補補,也不願去換個思路去想?

第一反應是自己的直覺,直覺一般憑借經驗做出反應,卻不一定靠譜,特別是那些經驗不足者的直覺。

對於彈出的直覺反應,我們應該用理性思維去進行判斷。

我們不要太懶惰了,任由着直覺去亂來,最后還得去幫它填坑。

 

參考大神的方法,修改后代碼如下:

str = input().split(',')
str_list = list(str)
integer_list = [int(x) for x in str_list]

current_sum = 0
largest_sum = 0

for num in integer_list:
    if current_sum + num > 0:
        current_sum += num
        largest_sum = max(largest_sum, current_sum)
    else:
        current_sum = 0

print(largest_sum)

   

參考:

https://www.nowcoder.com/questionTerminal/459bd355da1549fa8a49e350bf3df484


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM