《程式設計之美》 求陣列的子陣列的最大值

2021-07-08 09:31:27 字數 1785 閱讀 5084

問題:

求陣列的子陣列的最大值

分析與解法:

【解法一】

窮舉法,把每個子陣列的和求出來並比較,輸出最大值。時間複雜度為o(n^2)

**:

int maxsum(int *arr, int n)

return max;

}

【解法二】

將所給的陣列分為長度相等的兩部分,分別求出兩個陣列各自的最大子陣列的和,那麼原陣列的最大子陣列的和有三種情況:

[0, n-1]的最大子陣列的和與[0, n/2-1]的最大子陣列的和相同;

[0, n-1]的最大子陣列的和與[n/2, n]的最大子陣列的和相同;

[0, n-1]的最大子陣列橫跨arr[n/2]與arr[n/2-1]。

第1、2兩種情況是規模減半的相同子問題,可以通過遞迴求解,時間複雜度為o(nlogn)。

第3種情況,只要計算出以arr[n/2-1]為結尾的一段陣列最大和s1=sum1[i…n/2-1]和arr[n/2]為開頭一段陣列最大和s2=sum2[n/2…j],最後s=s1+s2。只需要遍歷一次陣列,時間複雜度為o(n)。

故總的時間複雜度為o(nlogn)

【解法三】

使用動態規劃的方法,考慮陣列第乙個元素arr[0],以及和最大的子陣列[i, j]之間的關係,有以下三種情況:

0 = i = j,arr[0]本身構成和最大的子陣列;

0 = i < j,和最大的子陣列從arr[0]開始;

0 < i < j,和最大的子陣列不包括arr[0]。

假設已經知道[1, n-1]中子陣列和的最大值是all[1],包含arr[1]的子陣列和的最大值是start[1],那麼[0, n-1]的子陣列和的最大值是max。時間複雜度為o(n)。

**:

int

max(int x, int y)

int maxsum(int *arr, int n)

return

all[0];

}

空間上對其進行優化,可以使用兩個變數代替使用兩個陣列。

int

max(int x, int y)

int maxsum(int *arr, int n)

return

all;

}

【解法四】

因為當乙個數加上乙個正數時,和會增加;加上乙個負數時,和會減少。如果當前得到的和是個負數,那麼這個和在接下來的累加中應該拋棄並重新清零,否則這個負數將會減少接下來的和。所以解法可以是如果當前和為負數,那麼就放棄前面的累加和,從陣列中的下乙個數再開始計數,時間複雜度為o(n)

int maxsum(int *arr, int n)

if(msum == 0)//若全為負數,則返回最大的負數

}return msum;

}

擴充套件問題:

1.若陣列首尾相連,如何求陣列的子陣列的最大值?

可以把問題分為兩種情況:

(1)沒有跨過arr[n-1]到arr[0](原問題);

(2)跨過arr[n-1]到arr[0]。

對於第(2)種情況,只要找到以arr[0]開頭的和最大的子陣列[0, i]和以arr[n-1]結尾的和最大的子陣列[j, n-1]。若i <= j,則直接將和相加;若j < i,則子陣列就是[0, n-1]。

總的時間複雜度仍是o(n)

程式設計之美 求陣列的子陣列之和的最大值

前段子時間舍友恒恒問了我乙個問題 怎樣在乙個陣列中找到乙個子陣列使得各個元素之和最大,當時自己想了片刻,設定乙個變數sum,就說從左邊開始變數整個陣列,乙個個相加到sum中,發現了sum 0的話,就把sum設定為0就可以了,後來想了下,得到的結果未能保證正確,我們應該在遍歷的過程中儲存下sum的最大...

求陣列的子陣列之和的最大值(程式設計之美)

題目要求 乙個有n個整數元素的一維陣列 a 0 a 1 a n 2 a n 1 這個陣列當然有很多子陣列,那麼子陣列中和最大值是多少呢?1 子陣列是連續的 2 求子陣列的和,不用求子陣列的具體位置 3 陣列的元素時整數,所以陣列可能包含有正整數 零 負整數 解法一 暴力解法,從陣列的第0位開始遍歷陣...

程式設計之美2 14 求陣列的子陣列之和的最大值

問題描述 乙個有n個整數元素的一維陣列 a 0 a 1 a n 1 它包含很多子陣列,求子陣列之和的最大值,當陣列元素全部為負的時候,有兩種處理辦法,第一種是返回0,第二種是返回陣列中最大的負數。解法1 使用暴力法,假設最大的一段陣列為a i a j 則對i 0 n 1 j i n 1,遍歷一遍,求...