/*!
\author LiuBao
\date 2011/3/24
\brief 求子数组的最大和
输入一个整形数组,数组里有正数也有负数。
数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
求所有子数组的和的最大值。要求时间复杂度为O(n)。
例如:输入的数组为1, -2, 3, 10, -4, 7, 2, -5,和最大的子数组为3, 10, -4, 7, 2,
因此输出为该子数组的和18。
思路:对长度为N的数组a从左到右扫描求和,抛弃小于0的子数组和,记函数为Sum(i)。
1、Sum(0) = a[0]
2、Sum(i) = Sum(i - 1) > 0 ? Sum(i - 1) + a[i] : a[i], (0 < i <= N - 1)
Sum(i)(0 <= i <= N - 1)中最大的,Max(Sum(i)),即为最大子数组和。
*/
#include <stdio.h>
#include <stdlib.h>
 
/*!
经典递归算法,直接使用状态转移,最大值保存在*sum中
\param array 数组
\param i 递归下标i
\param sum 最大值变量指针
\return Sum(i)
*/
int max_sum_old(const int *array, int i, int *sum)
{
    if(i)
    {
        int last_sum = max_sum_old(array, i - 1, sum);          //last_sum = Sum(i - 1)
 
        if(last_sum > *sum) *sum = last_sum;                    //更新*sum使之始终等于max(Sum(i))
 
        return last_sum > 0 ? last_sum + array[i] : array[i];   //Sum(i) = Sum(i - 1) > 0 ? Sum(i - 1) + a[i] : a[i]
    }
    else
        return array[0];                                        //Sum(0) = a[0]
}
 
/*!
在线算法,遍历过程能够直接计算出所需的状态值,返回最大子序列和
\param array 数组
\param n 数组元素个数
\return 数组中最大子序列和
*/
int max_sum(const int *array, int n)
{
    int i;                                                      ///< 遍历下标
    int sum = array[0];                                         ///< 最大子序列和
    int current = 0;                                            ///< 当前子序列和
    int new_start = -1;                                         ///< 新子序列开始位置
    int start = -1, end = -1;                                   ///< 最大子序列开始、结束位置
 
    for(i = 0; i < n; ++i)
    {
        if(current > 0)                                         // 当前子序列和 > 0
            current += array[i];                                // 向后扩展子序列,使之包含a[i]
        else                                                    // 当前子序列和 <= 0
        {
            current = array[i];                                 // 抛弃前一个子序列,重新计算当前子序列
            new_start = i;                                      // 记录新子序列的开始位置
        }
 
        if(current > sum)                                       // 若当前子序列和 > 最大子序列和
        {
            sum = current;                                      // 最大子序列和更新为当前子序列和
            start = new_start;                                  // 保存当前子序列的开始位置
            end = i;                                            // 保存当前子序列的结束位置
        }
    }
 
    printf("start: %d, end: %d\n", start, end);                 // 打印最大子序列开始、结束位置
 
    return sum;
}
 
int main()
{
    int dataSet[] = {1, -2, 3, 10, -4, 7, 2, -19, 3, 6};        ///< 测试数据集合
 
    /* 使用递归算法输出最大子序列和 */
    int sum = 0;
    max_sum_old(dataSet, sizeof(dataSet) / sizeof(int), &sum);
    printf("Max Sum: %d\n", sum);
 
    /* 使用在线算法输出最大子序列和 */
    printf("Max Sum: %d\n", max_sum(dataSet, sizeof(dataSet) / sizeof(int)));
 
    return 0;
}

转载于:https://www.cnblogs.com/codingmylife/archive/2011/03/24/1993655.html

练习系列 - 5、求子数组的最大和相关推荐

  1. 微软面试题系列(三):求子数组的最大和

    题目大意: 输入一个×××数组,数组里有正数也有负数. 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和. 求所有子数组的和的最大值.要求时间复杂度为 O(n). 例如输入的数组为 1, ...

  2. 算法 求子数组的最大和 C

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! //** ...

  3. 求子数组的最大和要求O(n)

    //求子数组的最大和 //输入一个整形数组.有整数也有负数,数组中连续一个或多个子数组,每一个子数组都有一个和,求全部子数组的和的最大值,要求时间复杂度O(n) #include<iostrea ...

  4. 程序员面试题100题第03题——求子数组的最大和

    题目:输入一个整型数组,数组里有整数也有负数.数组中连续的一个或者多个整数组成一个子数组,每个子数组都有一个和.求所有子数组的和的最大值. 要求时间复杂度为O(n). 分析: 方法一: 当我们加上一个 ...

  5. 程序员面试100题之九:求子数组的最大和

    题目:输入一个整形数组,数组里有正数也有负数.数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和.求所有子数组的和的最大值.要求时间复杂度为O(n). 例如输入的数组为1, -2, 3, ...

  6. 【算法07】求子数组的最大和

    题目:输入一个整型数组,数组里面有正数也有负数,数组中的连续一个或者多个整数组成一个子数组,每一个子数组都有一个和,求所有子数组和的最大值.要求时间复杂度为O(n). 例如:输入数组为{1,-2,3, ...

  7. python求子集_【算法07】求子数组的最大和

    题目:输入一个整型数组,数组里面有正数也有负数,数组中的连续一个或者多个整数组成一个子数组,每一个子数组都有一个和,求所有子数组和的最大值.要求时间复杂度为O(n). 例如:输入数组为{1,-2,3, ...

  8. 数组最大可以开多大_每日算法系列【LeetCode 689】三个无重叠子数组的最大和

    题目描述 给定数组 由正整数组成,找到三个互不重叠的子数组的最大和. 每个子数组的长度为 ,我们要使这 个项的和最大化. 返回每个区间起始索引的列表(索引从 0 开始).如果有多个结果,返回字典序最小 ...

  9. 算法进阶面试题07——求子数组的最大异或和(前缀树)、换钱的方法数(递归改dp最全套路解说)、纸牌博弈、机器人行走问题

    第一题 给定一个数组,求子数组的最大异或和. 一个数组的异或和为,数组中所有的数异或起来的结果. 简单的前缀树应用 暴力方法: 先计算必须以i结尾的子数组的异或和,然后再计算机i+1的,以此类推... ...

最新文章

  1. python3 configparse 配置模块
  2. 解决vue单页路由跳转后scrollTop的问题
  3. 1300多名硕博研究生被清退!全都是活该?真相有时候比表面更让人无奈......
  4. nofollow标签_nofollow标签是什么?如何使用
  5. python删除部分字符串_如何删除python列表中的部分字符串?
  6. android制作下拉选择_Excel制作一、二、三级下拉菜单技巧,你一定不能错过
  7. ASP.NET 生命周期(原文翻译)
  8. 【解决方法】jdb2/sdb1-8 io使用过高
  9. MapReduce 初学总结
  10. JavaScript算术运算中前加加与后加加
  11. 在JavaScript中实现继承的几种方式
  12. webstorm+vue组件开发准备
  13. java中打开eclipse_关于Java:如何在Eclipse中打开jar文件
  14. vue利用【​v-viewer插件】实现单张图片以及多张图片的(触屏缩放和拖动)
  15. java中英文汉语混合排序_Java编程实现中英混合字符串数组按首字母排序的方法...
  16. css动态特效 @keyframes
  17. C++整型(short,int,long,longlong)
  18. seo全攻略_seo教程_一张SEO全攻略技术图包含所有SEO技术要点
  19. RIB表与FIB表、ARP表与FDB表
  20. kalman简单例子——初始化参数对kalman性能的影响

热门文章

  1. javascript 函数 有任意多个参数/可变参数/动态参数
  2. python分位数回归模型_如何理解分位数回归风险价值 (VaR) 模型?
  3. 用PHP删除一条记录mysql,php – 如何使用jquery删除mysql记录
  4. 风控建模 python 知乎_风控建模基本要求及面试问题小结
  5. word2vec应用场景_word2vec有什么应用?
  6. nslang oracle_RAC11g+DG 高可用容灾方案部署
  7. zeppelin安装使用
  8. springboot通过Intellij指定端口
  9. openpyxl库,1秒合并多张表格并设置图表格式
  10. 就是这么流弊!三行Python代码,让数据处理速度提高2到6倍