53. 最大子数组和 (最大子序和)

描述

给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

子数组 是数组中的一个连续部分。

链接

53. 最大子数组和 - 力扣(LeetCode) (leetcode-cn.com)

 

解法

对于 贪心算法而言:

  • 贪心贪的是哪里呢?
  • 如果 -2 1 在一起,计算起点的时候,一定是从1开始计算,因为负数只会拉低总和,这就是贪心贪的地方!
  • 局部最优:当前“连续和”为负数的时候立刻放弃,从下一个元素重新计算“连续和”,因为负数加上下一个元素 “连续和”只会越来越小。
  • 全局最优:选取最大“连续和”
  • 局部最优的情况下,并记录最大的“连续和”,可以推出全局最优。
 1 class Solution {
 2     // 思路1:贪心法
 3     public int maxSubArray1(int[] nums) {
 4         if (nums.length == 1) {
 5             return nums[0];
 6         }
 7         int sum = Integer.MIN_VALUE;
 8         int count = 0;
 9         for (int i = 0; i < nums.length; i++) {
10             count += nums[i];
11             // 取区间累计的最大值(相当于不断确定最大子序终止位置)
12             sum = Math.max(count, sum); 
13             if (count < 0) { // 负数会拉低总和,去掉,让count为0,到下一个循环重新选取
14                 count = 0;
15             }
16         }
17         return sum;
18     }
19 
20     // 思路2:动态规划
21     public int maxSubArray(int[] nums) {
22         if (nums.length < 1) {
23             return 0;
24         }
25         int tmpSum = 0, res = nums[0]; 
26         for (int num : nums) {
27             // tmpSum + num < num 时,说明 tmpSum <= 0,需要从新的num中选取
28             tmpSum = Math.max(tmpSum + num, num);
29             // 当res < tmpSum 时,说明是之前tmpSum加的num负增益了,依然用res = res不选取
30             res = Math.max(res, tmpSum);
31         }
32         return res;
33     }
34 }

时间复杂度:O(n),额外空间复杂度O(1)

 

参考

carl

posted @ 2021-12-22 11:56  DidUStudy  阅读(39)  评论(0编辑  收藏  举报