问题链接:https://leetcode.com/problems/maximum-subarray/#/description
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.
这可是我第一次独立做出来动规的题,虽然是最简单的,不过还是好开心啊,哈哈。
public class Solution {
public int maxSubArray(int[] nums) {
/*
专项练习,所以思路肯定是用动规,那么重点就是表示状态和找出状态转移方程。
状态转移方程的核心思想就是之前的积累如果是正的,那么就是有用的,应该加上,否则负的没啥用,就弃了算了
状态表示:s[i]表示以第i个位置结尾的子串的最大和,那么最后问题的解就是max(s[i])
状态转移方程:s[i] = s[i - 1] > 0?s[i - 1] + nums[i]:nums[i]
*/
int len = nums.length;
int maxSum = Integer.MIN_VALUE;
int[] s = new int[len];
s[0] = nums[0];
maxSum = s[0];
for(int i = 1; i < len; i++){
s[i] = s[i - 1] > 0 ? s[i - 1] + nums[i] : nums[i];
if(s[i] > maxSum){
maxSum = s[i];
}
}
return maxSum;
}
}
打败了62.86%的Java代码。来到讨论区学习一下。
链接地址:https://discuss.leetcode.com/topic/6413/dp-solution-some-thoughts
思考的过程是非常棒的。
Analysis of this problem:
Apparently, this is a optimization problem, which can be usually solved by DP. So when it comes to DP, the first thing for us to figure out is the format of the sub problem(or the state of each sub problem). The format of the sub problem can be helpful when we are trying to come up with the recursive relation.
At first, I think the sub problem should look like: maxSubArray(int A[], int i, int j), which means the maxSubArray for A[i: j]. In this way, our goal is to figure out what maxSubArray(A, 0, A.length - 1) is. However, if we define the format of the sub problem in this way, it’s hard to find the connection from the sub problem to the original problem(at least for me). In other words, I can’t find a way to divided the original problem into the sub problems and use the solutions of the sub problems to somehow create the solution of the original one.
So I change the format of the sub problem into something like: maxSubArray(int A[], int i), which means the maxSubArray for A[0:i ] which must has A[i] as the end element. Note that now the sub problem’s format is less flexible and less powerful than the previous one because there’s a limitation that A[i] should be contained in that sequence and we have to keep track of each solution of the sub problem to update the global optimal value. However, now the connect between the sub problem & the original one becomes clearer:
maxSubArray(A, i) = maxSubArray(A, i - 1) > 0 ? maxSubArray(A, i - 1) : 0 + A[i];
And here’s the code
public int maxSubArray(int[] A) {
int n = A.length;
int[] dp = new int[n];//dp[i] means the maximum subarray ending with A[i];
dp[0] = A[0];
int max = dp[0];
for(int i = 1; i < n; i++){
dp[i] = A[i] + (dp[i - 1] > 0 ? dp[i - 1] : 0);
max = Math.max(max, dp[i]);
}
return max;
}
链接地址:https://discuss.leetcode.com/topic/5000/accepted-o-n-solution-in-java
这个讲得好清楚,经典方法一定要背下来。
this problem was discussed by Jon Bentley (Sep. 1984 Vol. 27 No. 9 Communications of the ACM P885)
the paragraph below was copied from his paper (with a little modifications)
algorithm that operates on arrays: it starts at the left end (element A[1]) and scans through to the right end (element A[n]), keeping track of the maximum sum subvector seen so far. The maximum is initially A[0]. Suppose we’ve solved the problem for A[1 .. i - 1]; how can we extend that to A[1 .. i]? The maximum
sum in the first I elements is either the maximum sum in the first i - 1 elements (which we’ll call MaxSoFar), or it is that of a subvector that ends in position i (which we’ll call MaxEndingHere).
MaxEndingHere is either A[i] plus the previous MaxEndingHere, or just A[i], whichever is larger.
public static int maxSubArray(int[] A) {
int maxSoFar=A[0], maxEndingHere=A[0];
for (int i=1;i