题目描述
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.
给一个数组,求其中连续元素的最大和(要求时间复杂度O(n))
解题思路
这种题,暴力枚举也可以,把所有连续子数组都列出来,最后再比较它们的和,得出最大和。但是,时间复杂度过高!
题目中连续元素个数是不确定的,对于这种不确定性较大的题目通常可以考虑动态规划。
按照习惯,假设dp[i]:数组共i个元素时,能得到的连续子数组的最大和。
我们会发现找不到dp[i]和dp[i-1]的关系呀,写不出状态转移方程。
所以转换思路:
dp[i] : 以第i个元素为结尾的连续子数组的最大和
如何从dp[i-1]得到dp[i]呢?
若dp[i-1]为正,dp[i]就把它算上,dp[i]=dp[i-1]+nums[i]
若dp[i-1]为负,dp[i]就不管它,dp[i]=nums[i]
简化一下,状态方程:dp[i]=Math.max(dp[i-1]+nums[i],nums[i]);
求出数组元素所有的dp[i],最后进行比较,最大的那个就是所求的结果。
实现代码
根据上述思路可得Java代码:.
public int maxSubArray(int[] nums) {
//动态规划,从结尾开始向前找
int[] dp=new int[nums.length]; //dp[i]表示以第i个元素结尾的连续元素的最大的和
dp[0]=nums[0]; //先以第一个元素为结尾,dp[i]就是该元素本身
int res=nums[0]; //res用来存放较大的dp[i]值----即最终所求
for(int i=1;i<nums.length;i++){ //再以第二个元素为结尾,依次求出dp[i]
//算出以所有元素结尾的dp[i]
//若dp[i-1]为负,dp[i]就不算上它;为正就加上它
dp[i]=Math.max(dp[i-1]+nums[i],nums[i]);
//比较所求的dp[i],较大的就是想要的结果
if(res<dp[i]){
res=dp[i];
}
}
return res;
}