Given an integer array?nums, find the contiguous subarray?(containing at least one number) which has the largest sum and return its sum.
Example:
Input:[-2,1,-3,4,-1,2,1,-5,4],
Output:6
Explanation:[4,-1,2,1] has the largest sum = 6.
Follow up:
If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.
尋找和最大的子串,子串必須是連續的,若將數組中每個數累加,則時間復雜度為0(n^2),題目還要求用分治法Divide and Conquer Approach來解,這個分治法的思想就類似于二分搜索法,從數組中間開始,分別向左向右進行累加,得到最大的累加和,然后再與左邊、右邊最大的累加和比較,得出最大累加和,時間復雜度為O(nlogn)。
注意點:
為減少空間復雜度,函數傳參使用實參而不用形參。
代碼:
int max(int n,int m)
{
? ? return n>m?n:m;
}
int getmax(vector<int>&nums,int left,int right)? //使用實參(&),而不用形參
{
? ? if(left>=right)
? ? ? ? return nums[left];
? ? int mid = (left+right)/2;
? ? int leftMax=getmax(nums, left, mid-1);
? ? int rightMax=getmax(nums, mid+1, right);
? ? int midMax=nums[mid];
? ? int t=midMax;
? ? for(int i=mid-1;i>=left;i--)
? ? {
? ? ? ? t+=nums[i];
? ? ? ? midMax=max(midMax,t);
? ? }
? ? t=midMax;
? ? for(int i=mid+1;i<=right;i++)
? ? {
? ? ? ? t+=nums[i];
? ? ? ? midMax=max(midMax,t);
? ? }
? ? return max(midMax,max(leftMax,rightMax));
}
int maxSubArray(vector<int>& nums) {
? ? if(nums.empty())
? ? ? ? return 0;
? ? return getmax(nums,0,nums.size()-1);
}
網上還有兩種方法:
https://www.cnblogs.com/bugfly/p/3922390.html
動態規劃,假設start[i]為a[i],a[i+1]...a[n-1]數組中以a[i]開頭的最大字段和,all[i]為a[i],a[i+1]...a[n-1]數組的最大字段和,則有
start[i] = max{a[i], start[i+1]+a[i]}
all[i] = max{start[i], all[i+1]}
此時時間復雜度為O(n),空間復雜度也為O(n),不過空間可以優化為O(1),為便于理解,不作優化處理了,代碼如下:
1 class Solution {
2 public:
3? ? int maxSubArray(int A[], int n) {
4? ? ? ? int start[n];? ? ? //start[i]為a[i],a[i+1]...a[n-1]數組中以a[i]開頭的最大字段和
5? ? ? ? int all[n];? ? ? ? //all[i]為a[i],a[i+1]...a[n-1]數組的最大字段和
6? ? ? ? memset(start, 0, sizeof(start));
7? ? ? ? memset(all, 0, sizeof(all));
8? ? ? ? start[n-1] = all[n-1] = A[n-1]; //初始化
9? ? ? ? for(int i=n-2; i>=0; --i) {
10? ? ? ? ? ? start[i] = max(A[i], start[i+1]+A[i]);
11? ? ? ? ? ? all[i] = max(start[i], all[i+1]);
12? ? ? ? }
13? ? ? ? return all[0];
14? ? }
15 };
還有一種Kadane算法,相當巧妙,時間復雜度亦為O(n),空間復雜度為O(1),具體請問度娘,代碼如下:
1 class Solution {
2 public:
3? ? int maxSubArray(int A[], int n) {
4? ? ? ? int ans = -0x3fffffff;? //預處理最小值
5? ? ? ? int sum = 0;
6? ? ? ? for(int i=0; i<n; ++i) {
7? ? ? ? ? ? sum += A[i];? ? //每次計算連續元素
8? ? ? ? ? ? ans = max(ans, sum);? //判斷ans是否又變大了
9? ? ? ? ? ? if( sum < 0 ) sum = 0;? //如果sum第一次小于0,立即更新,子數組重新開始
10? ? ? ? }
11? ? ? ? return ans;
12? ? }
13 };