2018-05-27

繼續 算法導論 最大子數組問題,線性時間,這次把索引,也計算出來

思路和代碼,抄襲 https://www.cnblogs.com/jimmy1989/p/8476916.html
感謝作者。
擴展-記錄索引值

這里因為與代碼結合著討論的,所以下標從0開始。
這里再說一下兩個自定義名詞:
前最大子數組:不包含當前元素的最大子數組
邊界最大子數組:只包含當前元素和不只包含當前元素,兩種情況的較大值

我們以數組{1,-2,3,10,-4,7,2,-48}為例。
初始時兩個索引都為0,最大子數組和邊界最大子數組都是1;
當迭代索引為1時,本次值為-2,前一元素的邊界最大子數組為1,所以邊界最大子數組為-1,前最大子數組為1,本次迭代的最大子數組為前最大子數組,值為1,不更新索引;
當迭代索引為2時,本次值為3,前邊界最大子數組為-1,所以邊界最大子數組為3;前最大子數組為1,本次迭代的最大子數組為邊界最大子數組,值為3;此時需要把起始索引和終止索引都更新為當前索引,即2;
當迭代索引為3是,本次值為10,前邊界最大子數組為3,所以邊界最大子數組為13,前最大子數組為3,本次迭代的最大子數組為邊界最大子數組,值為13;此時需要把終止索引更新為當前索引,卻不能更新起始索引;
…………
索引為2和索引為3的共同點在于,都是邊界最大子數組大于前最大子數組,都更新了終止索引;差別在于,索引2為時,邊界最大子數組只包含了索引對應的值,所以可以更新起始索引;而索引3的邊界最大子數組也包含了前一元素,所以只能更新終止索引。

此時可以把需要更新索引的情況概括如下:
條件①:本次的邊界最大子數組只包含當前值,且大于前最大子數組,則更新起始索引;
條件②:本次的邊界最大子數組大于前最大子數組,則更新終止索引;

更新終止索引的條件②應該是充分且必要的,然而更新起始索引的條件①是充分的,確并不是必要的。考慮一下數組{4,-5,1,5},當索引為2時,邊界最大子數組為1,前最大子數組為4,只滿足條件1的前半部分,然而整個數組的最大子數組的起始索引卻是2。所以條件①需要進行補充。

以下是第二個版本的兩個條件:
條件①:本次的邊界最大子數組只包含當前值 ,

(這里說明,如果在后面出現最大子數組,那么,索引從這里開始,
這里把,另一個網站的解釋,復制過來,感謝作者,允許我抄襲,引用
https://blog.csdn.net/songxueyu/article/details/47005557
“在已知A[1...j]的最大子數組的情況下,可以在線性時間內找出形如A[i..j+1]的最大子數組”
這句話里面描述的方法沒有說出來.這里我先把我的結論說出來,接下來再證明。
( 由于原文中的終止索引用l ,小寫的L ,容易看錯,此處用zz 表示)
結論:在已知A[1...j]的最大子數組的情況下(假設A[1..j]的最大子數組是A[k...zz]),找出Ai..j+1的最大子數組是如下三個子數組中的最大和
1.A[k...zz]
2.A[k...j+1]
3.max{A[x...j+1] | x 取值范圍從 zz + 2 至 j + 1}

也就是說,如果新的最大子數組不是原來的最大子數組,那么新的最大子數組的終點必然是j+1.這個是顯而易見的。
假設新的最大子數組不是原來的,那么起點是哪里呢?
1.起點不可能小于k。因為如果小于k,那么說明有A[x...j+1]>A[k...j+1](x<k),即存在A[x...k-1]>0,這顯然是不可能的。
2.起點不可能大于k小于等于zz。因為如果那樣的話,說明有A[x...j+1]>A[k...j+1](k<x<=zz),即A[k...x-1]<0,即最大子數組的起點到它中間某個點小于0,這是不可能的。
3.起點不可能位于zz+ 1,因為A[zz+1]必然小于0。)

條件②:本次的邊界最大子數組大于前最大子數組 (師傅,我又發現一個更大的人參果。)
當滿足條件①時,把當前索引記錄為緩存索引,但并不更新起始索引;
繼續干活,繼續尋找
當滿足條件②時,更新終止索引為當前索引,并且,更新起始索引為緩存索引。
條件②的滿足總是要在條件①之后的。
條件①可能標志著一個新的開始,因為條件①可以重復滿足,每次滿足都應該更新緩存索引。 ,而條件②必定標志著一個結束。

# Hello World program in Python
    
print "Hello99999 World!\n"

def maxSubArray( array):

    length = len(array) 
    boundry = array[0]
    maxArray = array[0]
    # copy from https://www.cnblogs.com/jimmy1989/p/8476916.html,thank you 
    maxEndIndex = 0
    maxBeginIndex = 0
    tmpBeginIndex = 0

    for i in range(1, length):
        print '===============================>>>'+str(i)+'>>>go'
 
        if ( boundry  > 0 ):
            boundry += array[i]
            
        else:
            #now   boundry <= 0
            boundry = array[i]
            #we record  tmpBeginIndex for use 
            tmpBeginIndex=i
            
        if( maxArray < boundry ):
            maxArray = boundry
            maxEndIndex=i
            #if  boundry == array[i]:
            maxBeginIndex=tmpBeginIndex
  
    return [maxArray,maxBeginIndex,maxEndIndex]

#a=[130,-3,-250,120,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7,-99,88,12] 
a=[-13,1123,-25,8820,-3,16,-723,18,20,77,-12,-5,22,-15,-4,88,12,-789,999,8,-9,88]
#a=[1,1,1,1,1,1,1,1,-99,2,2,2,2,2,2,2,2,2,2] 
print maxSubArray(a)

result

$python main.py
Hello99999 World!

===============================>>>1>>>go
===============================>>>2>>>go
===============================>>>3>>>go
===============================>>>4>>>go
===============================>>>5>>>go
===============================>>>6>>>go
===============================>>>7>>>go
===============================>>>8>>>go
===============================>>>9>>>go
===============================>>>10>>>go
===============================>>>11>>>go
===============================>>>12>>>go
===============================>>>13>>>go
===============================>>>14>>>go
===============================>>>15>>>go
===============================>>>16>>>go
===============================>>>17>>>go
===============================>>>18>>>go
===============================>>>19>>>go
===============================>>>20>>>go
===============================>>>21>>>go
[9931, 1, 5]

木馬音響積木 木馬音響積木 木馬音響積木 木馬音響積木 木馬音響積木 木馬音響積木 木馬音響積木 木馬音響積木 木馬音響積木 木馬音響積木 木馬音響積木 木馬音響積木 木馬音響積木 木馬音響積木 木馬音響積木 木馬音響積木 木馬音響積木 木馬音響積木 木馬音響積木 木馬音響積木 木馬音響積木 木馬音響積木 木馬音響積木 木馬音響積木 木馬音響積木 木馬音響積木 木馬音響積木 木馬音響積木 木馬音響積木

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容