栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

55 最大子数组(Maximum Subarray)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

55 最大子数组(Maximum Subarray)

文章目录
    • 1 题目
    • 2 解决方案
      • 2.1 思路
      • 2.3 时间复杂度
      • 2.4 空间复杂度
    • 3 源码
    • 4 另解——贪心算法

1 题目

题目:最大子数组(Maximum Subarray)
描述:**给定一个整数数组,找到一个具有最大和的子数组,返回其最大和。每个子数组的数字在数组中的位置应该是连续的。子数组最少包含一个数 **

lintcode题号——41,难度——easy

样例1:

输入:nums = [−2,2,−3,4,−1,2,1,−5,3]
输出:6
解释:符合要求的子数组为[4,−1,2,1],其最大和为 6。

样例2:

输入:nums = [1,2,3,4]
输出:10
解释:符合要求的子数组为[1,2,3,4],其最大和为 10。
2 解决方案 2.1 思路

  常规思路可以采用暴力法,使用两个序号,两重循环遍历出所有子数组来找到最大的,时间复杂度为O(^2)。
  这题可以只使用O(n)的复杂度来解决,引入一个前缀和的概念,即从头部开始到该位置的前一位置的数值累加和,最小前缀和即为之前所有位置的前缀和中最小的那个,要找到最大的子数组的值,只要通过当前位置的累加值减去之前的最小前缀和即可,在一次循环内即可完成累加求和以及更新最小前缀和的操作。

2.3 时间复杂度

  时间复杂度为O(n)。

2.4 空间复杂度

  空间复杂度为O(1)。

3 源码

细节:

  1. 一边求当前累加和,一边求当前位置往前的最小前缀和,以当前位置结尾的最大子数组的值即为两者之差。

C++版本:

int maxSubArray(vector &nums) {
    // write your code here
    if (nums.empty())
    {
        return 0;
    }

    int maxSum = INT_MIN;
    int sum = 0; // 当前累加和
    int minPrefixSum = 0; // 最小的前缀和,不用记录下标
    for (int i = 0; i < nums.size(); i++)
    {
        sum += nums.at(i);
        maxSum = max(sum - minPrefixSum, maxSum); // 累加和-最小前缀和=子数组可能的最大值
        minPrefixSum = min(sum, minPrefixSum); // 更新最小前缀和
    }

    return maxSum;
}
4 另解——贪心算法

细节:

  1. 用贪心的思想也可以解,思路是一旦发现前面的子串为负,无法为整个串带来正收益,则抛弃该子串,重新开始计算。

C++版本:

int maxSubArray(vector &nums) {
    // write your code here
    if (nums.empty())
    {
        return 0;
    }

    int result = INT_MIN;
    int curSum = 0;
    for (int i = 0; i < nums.size(); i++)
    {
        curSum += nums.at(i);
        result = max(curSum, result);
        curSum = max(curSum, 0); // 子串只取大于0的
    }

    return result;
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/857699.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号