給定一個整數數組 nums
,找到一個具有最大和的連續子數組(子數組最少包含一個元素),返回其最大和。
示例:
輸入: [-2,1,-3,4,-1,2,1,-5,4], 輸出: 6 解釋: 連續子數組 [4,-1,2,1] 的和最大,爲 6。
1.思路:初始化dp[0] = nums[0],dp[i] = max{dp[i] + nums[i] , nums[i]}, max(dp[i])即爲所求。但爲了節省空間,可使用空間複雜度爲O(1)的解法。
時間複雜度O(N),空間複雜度O(1)解法:以maxsum記錄當前以nums[i]結尾的最大序列和,並更新總的最大子序列和ans.
int maxSubArray(vector<int>& nums) {
int ans = nums[0];
int maxsum = nums[0];
for(int i = 1; i < nums.size(); i++){
maxsum = maxsum + nums[i] > nums[i] ? maxsum + nums[i] : nums[i];
ans = maxsum > ans ? maxsum : ans;
}
return ans;
}
2.分治遞歸。(Divide and Conquer)
最大子序列無非出現在三個位置:左邊、右邊、中間,於是想到用遞歸的思路。
int maxSubArray(vector<int>& nums) {
return helper(nums,0,nums.size()-1);
}
int helper(vector<int>& nums, int left, int right){
if(left > right)
return INT32_MIN;
int mid = (left + right)/2;
int leftMax = 0,sum = 0;
for(int i = mid-1; i >= left; i--){
sum += nums[i];
leftMax = sum > leftMax ? sum : leftMax;
}
int rightMax = 0;
sum = 0;
for(int i = mid+1; i <= right; i++){
sum += nums[i];
rightMax = sum > rightMax ? sum : rightMax;
}
int leftAns = helper(nums,left,mid-1);
int rightAns = helper(nums,mid+1,right);
return max(leftMax + rightMax + nums[mid], max(leftAns,rightAns));
}