標籤:

Leetcode-Maximum Subarray

Find the contiguous subarray within an array (containing at least one number) which has the largest sum.

For example, given the array [-2,1,-3,4,-1,2,1,-5,4],

the contiguous subarray [4,-1,2,1] has the largest sum = 6.

這題我沒做出來,因為暴力枚舉感覺真的太low了,網上查了一下主要有兩種方法。

Kadane演算法:

def max_subarray(A):n max_ending_here = max_so_far = A[0]n for x in A[1:]:n max_ending_here = max(x, max_ending_here + x)n max_so_far = max(max_so_far, max_ending_here)n return max_so_farn

這種演算法看起來很短,但說實話理解起來還是有一定難度的,max_ending_here代表在每一個掃描點計算以該點數值為結束點的子數列的最大和(正數和),因為最大和子串中不可能包含求和值為負的前綴,例如 【-2, 1,4】 必然不能是最大子數列, 因為去掉值為負的前綴後【-2,1】, 可以得到一個更大的子數列 【4】,所以在求max_ending_here的時候其實一直在去掉負的前綴,而max_so_far代表的就是目前為止最大子串和。這種演算法時間複雜度可以達到最優的O(N)級別。

Divide and Conquer演算法:

#include <bits/stdc++.h>nusing namespace std;nn// Function to find Maximum subarray sum using n// divide and conquernint MaximumSum(int A[], int low, int high)n{nt// If array contains only one elementntif (high == low)nttreturn A[low];nnt// Find middle element of the arrayntint mid = (low + high) / 2;nnt// Find maximum subarray sum for the left subarray nt// including the middle elementntint leftMax = INT_MIN;ntint sum = 0;ntfor (int i = mid; i >= low; i--) nt{nttsum += A[i];nttif (sum > leftMax)ntttleftMax = sum;nt}nt/*nt為什麼不是:這種寫法結果是錯的 ntfor (int i = low; i <= mid; i++)nt{nttsum += A[i];nttif (sum > leftMax)ntttleftMax = sum;nt}nt*/nnt// Find maximum subarray sum for the right subarray nt// excluding the middle elementntint rightMax = INT_MIN;ntsum = 0;t// reset sum to 0ntfor (int i = mid + 1; i <= high; i++) nt{nttsum += A[i];nttif (sum > rightMax)ntttrightMax = sum;nt}nnt// Recursively find the maximum subarray sum for left subarray nt// and right subarray and tale maximumntint maxLeftRight = max(MaximumSum(A, low, mid), ntttMaximumSum(A, mid + 1, high));nnt// return maximum of the threentreturn max(maxLeftRight, leftMax + rightMax);n}nnint main()n{ntint arr[] = { -2,1,-3,4,-1,2,1,-5,4 };ntint n = sizeof(arr) / sizeof(arr[0]);nntcout << "The Maximum sum of the subarray is " << ntttMaximumSum(arr, 0, n - 1);nntreturn 0;n}n

用分治法也可以做出來,時間複雜度O(NlogN),其中INT_MIN is a macro that expands to the smallest (most negative) value that can be stored in a variable of type int.

INT_MAX is a macro that expands to the largest (most positive) value that can be stored in an int.這是c++的語法。英文解釋很清楚了。

但我有個疑惑在於:

/*

t為什麼不是:這種寫法結果是錯的

tfor (int i = low; i <= mid; i++)

t{

ttsum += A[i];

ttif (sum > leftMax)

tttleftMax = sum;

t}

*/

在求leftmax的時候用這種方式for循環,為什麼得出的結果就是錯誤的呢?

參考鏈接:

清晰解題: 尋找最大子數列-Kadane演算法

zh.wikipedia.org/wiki/%

quora.com/What-is-INT_M

techiedelight.com/maxim


推薦閱讀:

Unity 5 發布了,但是否 Unity 做的遊戲與 Unreal 相比要顯得粗糙很多?
Qt 重繪問題?
計算機專業C++應該怎麼教?
C++遊戲開發擇業前景?
微軟究竟遇到了什麼問題使得他們到現在都無法在 C1 中實現兩步名稱查找?

TAG:LeetCode | Python | C |