【剑指offer】面试题31:连续子数组的最大和

题目:输入一个整型数组,数组里有正数也由负数。数组中一个或者连续的多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为 O(n)。

例如输入的数组为{1,-2,3,10,-4,7,2,-5},其最大的子数组为{3,10,-4,7,2},因此所有子数组的和的最大值为 18。

应用动态规划法:

我们需要保存两个值,一个存放遍历到当前位置的和kCurSum,另一个存放遍历到当前位置时的最大和kGreatestSum。假设现在我们遍历到第K个位置的元素:

1、如果当前的和kCurSum小于等于0,那么我们置当前和为遍历到的当前元素arr[k];

2、如果,kCurSum大于 0, 那么我们将 kCurSum 置为 kCurSum 与 arr[k] 的和;

3、将变化后的 kCurSum 与当前最大和 kGreatestSum 比较;

4、如果前者kCurSum 大于 后者kGreatestSum,将 kGreatestSum 置为 kCurSum;

4、否则,继续遍历;

完整代码如下:

 1 #include <iostream>
 2 #include <stdexcept>
 3
 4 bool isAllElemsNegative(int *arr, int len);
 5 int findMaxNum(int *arr, int len);
 6
 7 int findGreatestSumOfSubArray(int *arr, int len)
 8 {
 9     if(arr == NULL || len <= 0)
10         throw std::out_of_range("Invalid Input");
11
12     int nMaxSum = 0;
13     int curSum = 0;
14
15     if(isAllElemsNegative(arr, len))
16     {
17         return findMaxNum(arr, len);
18     }
19
20     for(int i = 0; i < len; ++i) // 数组存在正数
21     {
22         if(curSum <= 0)
23             curSum = arr[i];
24         else
25             curSum += arr[i];
26
27         if(curSum > nMaxSum)
28             nMaxSum = curSum;
29     }
30     return nMaxSum;
31 }
32
33 bool isAllElemsNegative(int *arr, int len)
34 {
35     bool isNegative = true;
36
37     for(int i = 0; i < len; ++i)
38     {
39         if(arr[i] >= 0)
40         {
41             isNegative = false;
42             break;
43         }
44     }
45     return isNegative;
46 }
47
48 int findMaxNum(int *arr, int len)
49 {
50     int num = arr[0];
51     for(int i = 1; i < len; ++i)
52     {
53         if(arr[i] > num)
54             num = arr[i];
55     }
56     return num;
57 }
58
59 int main(int argc, char *argv[])
60 {
61     // int arr[8] = {1, -2, 3, 10, -4, 7, 2, -5};
62     int arr[8] = {-3, -5, -2, -9, -12, -1, -90, -5};
63     int max = findGreatestSumOfSubArray(arr, 8);
64     std::cout << "The max Sum is: " << max << std::endl;
65
66     return 0;
67 }

本文完。

时间: 2024-12-21 22:47:13

【剑指offer】面试题31:连续子数组的最大和的相关文章

剑指offer面试题31连续子数组的最大和

一.题目描述 HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学.今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决.但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止).你会不会被他忽悠住? 二.解题思路 求连续子数组的最大和,首先想的到最笨的方法就是暴力解决,两个for循环,遍历数组找到和最大的子

【剑指offer】42、连续子数组的最大和

题目 输入一个整型数组,数组里有正数也有负数.数组的一个或连续多个整数组成一个子数组.求所有子数组的最大和.要求时间复杂度为O(n) 思路一 试着从头到尾累加每个数字,若发现有子数组和小于零,则加上后面的数字肯定会变小 因此丢弃这组子数组,从后面一个数字开始重新累加 例如{1,-2,3,10,-4,7,2,-5} 1+(-2)=-1 3+10-4+7+2=18 3+10-4+7+2-5=13 因此是18 需要注意的是,记录最大值的初始值要设置成INT_MIN,因为最大值可能是负数. class

剑指offer 30.时间效率 连续子数组的最大和

题目描述 HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学.今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决.但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止).给一个数组,返回它的最大连续子序列的和,你会不会被他忽悠住?(子向量的长度至少是1) 错误解法: public class FindG

面试题31 连续子数组的最大和

题目描述 HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学.今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决.但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止).你会不会被他忽悠住? 1 class Solution { 2 public: 3 vector<int> v; 4 int Fin

【剑指offer】Q31:连续子数组的组大和

简短的分析见:http://blog.csdn.net/shiquxinkong/article/details/17934747 def FindGreatestSumOfSubArray(array, index = None): curSum = 0 maxSum = 0 #return maxSum without the start and end index if index == None: for x in array: curSum = max(curSum, 0) curSu

【剑指offer】面试题 42. 连续子数组的最大和

面试题 42. 连续子数组的最大和 NowCoder 题目描述 输入一个整型数组,数组里有正数也有负数.数组中一个或连续的多个整数组成一个子数组.求所有子数组的和的最大值. 示例: 输入: [-2,1,-3,4,-1,2,1,-5,4], 输出: 6 解释: 连续子数组 [4,-1,2,1] 的和最大,为 6. 注意: 要求时间复杂度为 O(n). Java 实现 public class Solution { public int FindGreatestSumOfSubArray(int[]

动态规划:面试题42. 连续子数组的最大和

面试题42. 连续子数组的最大和 题目要求: 解题思路: 1. 定义子问题: dp[i] 为下标以 num[i] 结尾的数组字段 元素最大最短和,i表示子段到当前i位置 i: 2. 寻找关系式: 只有一个元素:dp[0] = num[0]; 两个元素:dp[i] 为num[0], num[1], num[0]+num[1]; 三个元素时:考虑前三个元素,如何求其最?大?子段和?还是分为两种情况讨论,第三个元素在最后的字串串内吗? 若第三个元素也包含在最后的字串串内,则dp[2] = max(dp

剑指Offer面试题31(java版):连续子数组的最大和

题目:输入一个整型数组,数组里有正数也有负数.数组中一个或连续的多个整数组成一个子数组. 求所有子数组的和的最大值.要求时间复杂度为O(n) 例如输入的数组为{1,-2,3,10,-4,7,2,-5} 看到该题目,很多人都能想到最直观的方法,即枚举出数组的所有子数组并求出他们的和.一个长度为n的数组,总共有n(n+1)/2个子数组.计算出所有的子数组的和,最快也需要O(n2)的时间.通常最直观的方法不会是最优的方法,面试官将提示我们还有更快的方法. 解法一:举例分析数组的规律: 我们试着从头尾逐

面试题:连续子数组的最大和

HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学.今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决.但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止).你会不会被他忽悠住? class Solution { public: int FindGreatestSumOfSubArray(vector

剑指OFFER----面试题42. 连续子数组的最大和

链接:https://leetcode-cn.com/problems/lian-xu-zi-shu-zu-de-zui-da-he-lcof/submissions/ 代码: class Solution { public: int maxSubArray(vector<int>& nums) { int res = INT_MIN, s = 0; for (auto x: nums) { if (s < 0) s = 0; s += x; res = max(res, s);