Brute Force
得到所有形成的subarray,计算sum然后得到最大值。
2D DP
dp[i][j]为position i到position j的array sum
dp[i][j] = dp[i][j-1] + num[j]
这个code有runtime error,谁能帮我看看不?
class Solution {
public:
int maxSubArray(vector<int>& nums) {
if(nums.empty()) return INT_MIN;
int n = nums.size();
int dp[n][n] = {0};
int mx = INT_MIN;
for(int i=0;i<n;i++){
dp[i][i] = nums[i];
mx = max(mx, dp[i][i]);
for(int j=i+1;j<n;j++){
dp[i][j] = dp[i][j-1] + nums[j];
mx = max(mx, dp[i][j]);
}
}
return mx;
}
};
Use vector can fix the runtime error but cannot fix the following Memory Limit Exceeded Error, 汗。。。
Reason: int dp[n][n] is not valid C++, array size must be known at compile time
Why aren't variable-length arrays part of the C++ standard?
这些array还可以分类为以j结尾的array们,在每个分类中我们可以找到分类的最大值,那么总的最大值也很好找了
每个分类的最大值如何找?dp[j] = max(dp[j-1] + nums[j], nums[j])
解法一:O(n) DP
Intuition: cut of here or continue
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int n = nums.size()+1, mx=INT_MIN;
int dp[n] = {0};
for(int j=1;j<n;j++){
dp[j] = max(dp[j-1]+nums[j-1], nums[j-1]);
mx = max(mx, dp[j]);
}
return mx;
}
};
优化 Greedy
only used dp[i-1] --> no need of the vector
class Solution {
public:
int maxSubArray(vector<int> &nums) {
int n = nums.size(), res=INT_MIN, pre=0;
for(int num: nums){
pre = max(pre+num, num);
res = max(pre, res);
}
return res;
}
};
解法二:O(nlogn) divide and conquer
Max Subarray occurs:
1. left side
2.right side
3. cross the mid
class Solution {
public:
int maxSubArray(vector<int> &nums) {
return helper(nums, 0, nums.size()-1);
}
int helper(vector<int>& nums, int left, int right){
if(right<=left) return nums[left];
int mid = left+(right-left)/2;
int lmax = helper(nums, left, mid-1);
int rmax = helper(nums, mid+1, right);
int mmax = nums[mid], t=nums[mid];
for(int i=mid-1;i>=left;i--){
t += nums[i];
mmax = max(mmax, t);
}
t=mmax;
for(int i=mid+1;i<=right;i++){
t += nums[i];
mmax = max(mmax, t);
}
return max(mmax, max(lmax, rmax));
}
};
Reference:
https://helloacm.com/c-coding-exercise-maximum-subarray-dynamic-programming-and-greedy-algorithm/