问题:
- 输入一个整型数组,数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。
要求时间复杂度为O(n)。
解决
//1、动态规划
class Solution {
public int maxSubArray(int[] nums) {
int cur, proMax=0, resMax=nums[0]; //当前数,当前和,最大和
for(int i=0;i<nums.length;i++){
cur=nums[i]; //获取当前值
proMax+=cur; //获取当前和
proMax=Math.max(cur,proMax); //获取当前最大值
resMax=Math.max(proMax,resMax); //获取最大值
}
return resMax;
}
}
//2、前缀和
class Solution {
public int maxSubArray(int[] nums) {
int min = 0;
int ans = Integer.MIN_VALUE;
int num = 0;
for(int i = 0 ; i < nums.length ; i ++){
num += nums[i]; //获取前i个数值
ans = Math.max(ans , num - min); //获取ans与当前前缀和的最大值
if(num<min){ //当num《min时,既是舍去当前缀和重新开始计算。
min = num;
}
}
return ans;
}
}
//3、二分
class Solution {
public class Status {
public int lSum, rSum, mSum, iSum;
public Status(int lSum, int rSum, int mSum, int iSum) {
this.lSum = lSum;
this.rSum = rSum;
this.mSum = mSum;
this.iSum = iSum;
}
}
public int maxSubArray(int[] nums) {
return getInfo(nums, 0, nums.length - 1).mSum;
}
public Status getInfo(int[] a, int l, int r) {
if (l == r) {
return new Status(a[l], a[l], a[l], a[l]);
}
int m = (l + r) >> 1;
Status lSub = getInfo(a, l, m);
Status rSub = getInfo(a, m + 1, r);
return pushUp(lSub, rSub);
}
public Status pushUp(Status l, Status r) {
int iSum = l.iSum + r.iSum;
int lSum = Math.max(l.lSum, l.iSum + r.lSum);
int rSum = Math.max(r.rSum, r.iSum + l.rSum);
int mSum = Math.max(Math.max(l.mSum, r.mSum), l.rSum + r.lSum);
return new Status(lSum, rSum, mSum, iSum);
}
}