题目
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例:
输入: [-2,1,-3,4,-1,2,1,-5,4],
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
思路一 动态规划
首先理解其遍历这个数组的方式,如果是暴力法的话,就是从头开始遍历递归
那么动态规划,自底向上,以某一结点结束 为基准来遍历数组
这样定义dp状态空间
dp状态方程:某一点的最大子序和 就是 当前元素自身最大,或者当前元素包含之前元素的最大子序和最大
dp[i] = max(nums[i], dp[i-1] + nums[i])
public class Solution {
public int maxSubArray(int[] nums) {
int len = nums.length;
if (len == 0) {
return 0;
}
int[] dp = new int[len];
dp[0] = nums[0];
for (int i = 1; i < len; i++) {
dp[i] = Math.max(nums[i], dp[i - 1] + nums[i]);
}
// 拿出最大值
int res = dp[0];
for (int i = 1; i < len; i++) {
res = Math.max(res, dp[i]);
}
return res;
}
}
复杂度分析
时间复杂度:O(N)
空间复杂度:O(N)
算法2 动态规划,优化
dp数组记录了数组里面以某一点结束为基准的所有点的最小子序和,因为只是需要最大的,所以用一个变量就能存储
class Solution {
public int maxSubArray(int[] nums) {
int sum = nums[0];
int temp = 0;
for (int i = 0; i < nums.length; i++) {
temp = temp + nums[i];
if (temp > sum) sum = temp;
if (temp <= 0) temp = 0;
}
return sum;
}
}
复杂度分析
时间复杂度:O(N)
空间复杂度:O(1)
算法3分治法
分为左边子序,右边子序,中间子序 递归
public int maxSubArray(int[] nums) {
return maxSubArrayDivideWithBorder(nums, 0, nums.length-1);
}
private int maxSubArrayDivideWithBorder(int[] nums, int start, int end) {
if (start == end) {
// 只有一个元素,也就是递归的结束情况
return nums[start];
}
// 计算中间值
int center = (start + end) / 2;
int leftMax = maxSubArrayDivideWithBorder(nums, start, center); // 计算左侧子序列最大值
int rightMax = maxSubArrayDivideWithBorder(nums, center + 1, end); // 计算右侧子序列最大值
// 下面计算横跨两个子序列的最大值
// 计算包含左侧子序列最后一个元素的子序列最大值
//从中间往左扫描
int leftCrossMax = Integer.MIN_VALUE; // 初始化一个值
int leftCrossSum = 0;
for (int i = center ; i >= start ; i --) {
leftCrossSum += nums[i];
leftCrossMax = Math.max(leftCrossSum, leftCrossMax);
}
// 计算包含右侧子序列最后一个元素的子序列最大值
//从中间往右扫描
int rightCrossMax = nums[center+1];
int rightCrossSum = 0;
for (int i = center + 1; i <= end ; i ++) {
rightCrossSum += nums[i];
rightCrossMax = Math.max(rightCrossSum, rightCrossMax);
}
// 计算跨中心的子序列的最大值
int crossMax = leftCrossMax + rightCrossMax;
// 比较三者,返回最大值
return Math.max(crossMax, Math.max(leftMax, rightMax));
}
作者:lizhiqiang-3
来源:力扣(LeetCode)