题目描述:
给定一个整数数组 nums
,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例:
输入:nums = [-2,1,-3,4,-1,2,1,-5,4] 输出:6 解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。
解题方法1:暴力解题。双层循环,遍历数组,第一层循环就是设置开始循环的位置,第二层循环开始遍历寻找最大和。此方法时间复杂度为 O(n^2),空间复杂度 O(1)。
public static int maxSubArray1(int[] nums) {
int sum = 0;
// result 始终记录最大子序和
int result = MIN_INT_VALUE;
if (nums.length == 1) {
return nums[0];
}
for (int i = 0; i < nums.length; i++) {
sum= 0;
for (int j = i; j < nums.length; j++) {
sum += nums[j];
result = sum > result ? sum : result;
}
}
return result;
}
解题方法2:贪心法。遍历数组,从头开始用 sum 累加,如果 sum 一旦加上 nums[i] 变为负数,那么就舍弃 sum,从nums[i+1] 开始从 0 重新累加 sum,因为已经变为负数的 sum 只会拖累总和 result。此方法时间复杂度为 O(n),空间复杂度 O(1)。
public static int maxSubArray(int[] nums) {
int sum = 0;
// result 始终记录最大子序和
int result = MIN_INT_VALUE;
if (nums.length == 1) {
return nums[0];
}
for (int i = 0; i < nums.length; i++) {
if (sum > 0) {
sum += nums[i];
} else {
sum = nums[i];
}
result = Math.max(result, sum);
}
return result;
}
j假如入参数组为:{-2, 1, -3, 4, -1, 2, 1, -5, 4},则以上两种方法得到的 result 都是 6,构成最大子序和的子序是 {4, -1, 2, 1}。
两种方法的完整代码如下所示:
package leetCode.easy.maxSubArray;
/**
* @ClassName: MaxSubArray
* @Author: jiaomubai
* @Date: 2021/9/14 16:47
* @Description: 最大子序和, LeetCode 题库第53题
*/
public class MaxSubArray {
public static int MIN_INT_VALUE = -2147483648;
public static int maxSubArray(int[] nums) {
int sum = 0;
// result 始终记录最大子序和
int result = MIN_INT_VALUE;
if (nums.length == 1) {
return nums[0];
}
for (int i = 0; i < nums.length; i++) {
if (sum > 0) {
sum += nums[i];
} else {
sum = nums[i];
}
result = Math.max(result, sum);
}
return result;
}
public static int maxSubArray1(int[] nums) {
int sum = 0;
// result 始终记录最大子序和
int result = MIN_INT_VALUE;
if (nums.length == 1) {
return nums[0];
}
for (int i = 0; i < nums.length; i++) {
sum= 0;
for (int j = i; j < nums.length; j++) {
sum += nums[j];
result = sum > result ? sum : result;
}
}
return result;
}
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
int[] nums = new int[]{-2, 1, -3, 4, -1, 2, 1, -5, 4};
int result = maxSubArray1(nums);
System.out.println("result = " + result);
long endTime = System.currentTimeMillis();
System.out.println("程序运行时间:" + (endTime - startTime) + "ms");
}
}
除此之外,此题还可使用动态规划的方法解决,后续更新...