題目連結(https://leetcode.com/problems/maximum-subarray/description/)
Given an integer array nums
, find the subarray with the largest sum, and return its sum.
演算法教科書會看到的經典題,程式設計師必會題!
nums
sum
1 <= nums.length <= 10^5
-10^4 <= nums[i] <= 10^4
Input: nums = [-2,1,-3,4,-1,2,1,-5,4]
Output: 6
Explanation: The subarray [4,-1,2,1] has the largest sum 6.
關鍵在於:最大子陣列可能出現在三個位置:
dp[i]
= 以 i
作為 結尾 的最大子陣列和(必須包含 nums[i]
)。dp[i] = max(nums[i], dp[i-1] + nums[i])
dp[i-1]
,可用兩個變數:currentSum
、maxSum
,空間 O(1)。nums[0]
,不要從 0 開始)。O(n)
O(1)
class Solution {
public:
int maxSubArray(vector<int>& nums) {
return divide_conquer(nums, 0, nums.size() - 1);
}
int divide_conquer(vector<int>& nums, int l, int r){
if(l == r) return nums[l]; //不能設定成0,得要使用更新後的l
int m = l + (r-l)/2;
int leftmax = divide_conquer(nums, l, m);
int rightmax = divide_conquer(nums, m+1, r);
int crossmax = cross_sum(nums, l, m, r);
return max({leftmax, rightmax, crossmax});
}
int cross_sum(vector<int>& nums, int l, int m, int r){
int leftsum = nums[m];
int sum = nums[m];
for(int i = m - 1; i >= l; i--){
sum += nums[i];
leftsum = max(leftsum, sum);
}
int rightsum = nums[m+1];
int sum2 = nums[m+1];
for(int i = m + 2; i <= r; i++){
sum2 += nums[i];
rightsum = max(rightsum, sum2);
}
return leftsum + rightsum;
}
};
# DP(Kadane's Algorithm)
// O(n) 解法 - 更優!
int maxSubArray(vector<int>& nums) {
int maxsum = nums[0];
int currentsum = nums[0];
for (int i = 1; i < nums.size(); i++) {
currentsum = max(nums[i], currentsum + nums[i]);
maxsum = max(maxsum, currentsum);
}
return maxsum;
}
nums = [-2, 1, -3, 4, -1, 2, 1, -5, 4]
初始化:
currentSum = -2
maxSum = -2
i=1: nums[1]=1
currentSum = max(1, -2+1) = 1
maxSum = max(-2, 1) = 1
i=2: nums[2]=-3
currentSum = max(-3, 1-3) = -2
maxSum = max(1, -2) = 1
i=3: nums[3]=4
currentSum = max(4, -2+4) = 4
maxSum = max(1, 4) = 4
i=4: nums[4]=-1
currentSum = max(-1, 4-1) = 3
maxSum = max(4, 3) = 4
i=5: nums[5]=2
currentSum = max(2, 3+2) = 5
maxSum = max(4, 5) = 5
i=6: nums[6]=1
currentSum = max(1, 5+1) = 6
maxSum = max(5, 6) = 6
...
最後答案 = 6
ps. 部分內容經 AI 協助整理