最大连续子序列的和问题(算法)

news2025/1/11 11:00:23

问题描述

给定一个有n(n≥1)个整数的序列,要求求出其中最大连续子序列的和。
在这里插入图片描述

蛮力法

暴力枚举

/**
 * 时间复杂度:O(n^3)
 * @param arr 序列[数组]
 * @param n 数组大小
 * @return int 
 */
int maxSubSum1(int arr[], int n) {
    int thisSum; // 子序列的和
    int maxSum = arr[0]; // 最大连续子序列的和
    for(int i = 0;i < n;i++) {
        for(int j = i;j < n;j++) { // 两重循环穷举所有的连续子序列
            // 计算子序列的和
            thisSum = 0;
            for(int k = i;k <= j;k++) {
                thisSum += arr[k];
            }
            // 通过比较求最大子序列的和
            if(thisSum > maxSum) {
                maxSum = thisSum;
            }
        }
    }
    return maxSum;
}

优化枚举法

暴力枚举存在的问题:
在这里插入图片描述
使用暴力枚举的时候存在重复计算的情况,可以改进来减少重复计算。
a[1,6] = a[1,5] + a[6]

在这里插入图片描述

// 优化枚举法  时间复杂度:O(n^2)
int maxSubSum2(int arr[], int n) {
    int thisSum; // 子序列的和
    int maxSum = arr[0]; // 最大连续子序列的和
    for(int i = 0;i < n;i++) {
        thisSum = 0;
        for(int j = i;j < n;j++) {
            thisSum+=arr[j];
            if(thisSum > maxSum) {
                maxSum = thisSum;
            }
        }
    }
    return maxSum;
}

改进的优化枚举法

对于 maxSubSum2() 算法,还可以进一步改进。

  • 在扫描序列的时候,如果扫描中遇到负数,当前子序列和 thisSum 将会减小,若 thisSum 为负数,表明前面已经扫描的那个子序列可以抛弃了,则放弃这个子序列,重新开始下一个子序列的分析,并置 thisSum 为0。
  • 若这个子序列和 thisSum 不断增加,那么最大子序列和 maxSum 也会不断增加。
// 改进的优化枚举法  时间复杂度:O(n)
int maxSubSum3(int arr[], int n) {
    int thisSum = 0; // 子序列的和
    int maxSum = arr[0]; // 最大连续子序列的和
    for(int i = 0;i < n;i++) {
        thisSum += arr[i];
        // 若当前子序列的和为负数,就重新开始下一子序列
        if(thisSum < 0) {
            thisSum = 0;
        }
        // 比较求最大连续子序列
        if(thisSum > maxSum) {
            maxSum = thisSum;
        }
    }
    return maxSum;
}

分治法

在这里插入图片描述

  1. 将数组 a[0,n-1] 分解为 a[0, n/2-1 ] 和 a[n/2, n-1 ];
  2. 递归求解子问题: 左半部分的最大连续子序列和A1=8, 右半部分的最大连续子序列和A2=12
  3. 合并子问题,得到原问题的最大子序列和。 若跨中点的最大连续子序列和A3; 则原序列的最大连续子序列和为max{A1,A2,A3}

求解跨中点的最大子序列的和:

在这里插入图片描述

  1. 记 mid = n/2 - 1
  2. 则A3可以分成两个部分:left + right
  3. left:以 a[mid] 为结尾的最大连续子序列的和;right:以 a[mid+1] 为开端的最大连续子序列的和
  4. 分别求出 left 和 right 即可得到 A3
int getMax(int a, int b, int c) {
    int temp = a > b ? a : b;
    int max = temp > c ? temp : c;
    return max;
}


// 分治法  时间复杂度:O(nlogn)
// left--数组起始下标,right--数组结束下标
int maxSubSum4(int arr[], int left, int right) {
    // 子序列只有一个元素时
    if(left == right) {
        if(arr[left] > 0) return arr[left];
        else return 0;
    }

    int maxLeftSum = 0, maxRightSum = 0;
    int maxLeftBorderSum = 0, leftBorderSum = 0;
    int maxRightBorderSum = 0, rightBorderSum = 0;
    
    int mid = (left + right)/2;

    maxLeftSum = maxSubSum4(arr, left, mid);
    maxRightSum = maxSubSum4(arr, mid+1, right);
	// 求出以左边加上a[mid]元素构成的序列的最大和
    for(int i = mid;i >= left;i--) {
        leftBorderSum += arr[i];
        if(leftBorderSum > maxLeftBorderSum) {
            maxLeftBorderSum = leftBorderSum;
        }
    }
	// 求出a[mid]右边元素构成的序列的最大和
    for(int j = mid+1;j <= right;j++) {
        rightBorderSum += arr[j];
        if(rightBorderSum > maxRightBorderSum) {
            maxRightBorderSum = rightBorderSum;
        }
    }
    return getMax(maxLeftSum, maxRightSum, maxLeftBorderSum+maxRightBorderSum);
}

动态规划

在这里插入图片描述
可以得到 dp[j] 的递推方程:
在这里插入图片描述
则序列a的最大连续子序列和等于dp[j](1≤j≤n)中的最大者。

// 动态规划  时间复杂度:O(n)
// 对于含有n个整数的序列a,设dp[j]表示以a[j]结尾的最大连续子序列和
int maxSubSum5(int arr[], int n) {
    int dp[n];
    dp[0] = arr[0];
    for(int i = 1;i < n;i++) {
        if(dp[i-1] > 0) {
            dp[i] = dp[i-1] + arr[i];
        } else {
            dp[i] = arr[i];
        }
    }
    // 查找dp[]数组中的最大者
    int maxSum = dp[0];
    for(int j = 0;j < n;j++) {
        if(dp[j] > maxSum) {
            maxSum = dp[j];
        }
    }
    return maxSum;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/118297.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

美团餐饮SaaS基于StarRocks构建商家数据中台的探索

作者&#xff1a;何启航&#xff0c;美团餐饮SaaS数据专家&#xff08;文章整理自作者在 StarRocks Summit Asia 2022 的分享&#xff09; 随着社会经济的发展&#xff0c;餐饮连锁商家越来越大&#xff0c;“万店时代”来临。对于美团餐饮 SaaS 来说&#xff0c;传统的 OLTP …

LeetCode 324 周赛

2506. 统计相似字符串对的数目 给你一个下标从 0 开始的字符串数组 words 。 如果两个字符串由相同的字符组成&#xff0c;则认为这两个字符串 相似 。 例如&#xff0c;"abca" 和 "cba" 相似&#xff0c;因为它们都由字符 a、b、c 组成。然而&#xff…

HQChart实战教程54-renko砖形K线图

HQChart实战教程54-renko砖形K线图 Renko砖形图效果图使用HQChart创建Renko初始化创建Renko配置参数说明ClassNameOption动态修改Renko配置参数完成demo代码Renko砖形图 Renko砖形图是仅测量价格变动的图表类型。 “ renko”一词源自日语单词“ renga”,意为“砖”。并非巧合…

day30【代码随想录】分割回文串、复原IP地址、子集

文章目录前言一、分割回文串&#xff08;力扣131&#xff09;二、复原IP地址&#xff08;力扣93&#xff09;三、子集&#xff08;力扣78&#xff09;总结前言 1、分割回文串 2、复原IP地址 3、子集 一、分割回文串&#xff08;力扣131&#xff09; 给你一个字符串 s&#xf…

前端开发:关于鉴权的使用总结

前言 前端开发过程中&#xff0c;关于鉴权&#xff08;权限的控制&#xff09;是非常重要的内容&#xff0c;尤其是前端和后端之间数据传递时候的请求鉴权校验。前端鉴权的本质就是控制前端视图层的显示和前端向后台所发送的请求&#xff0c;但是只有前端鉴权&#xff0c;没有后…

MyGDI+

文章目录[toc]界面设计Form窗口MenuStrip画笔其他选项界面美化整体框架设计DataStructureCPointPolylinePolygonSingletonGraphicFunctionForm事件处理成员变量事件处理总结界面设计 Form窗口 首先添加MenuStrip控件&#xff0c;随后在Form窗口属性界面根据个人爱好修改其图标…

请收下这份数字IC面试超强攻略!(内附大厂面试题目)

2022年马上就要结束了&#xff0c;想必今年有很多同学也已经感受到IC行业的门槛在不断提升&#xff0c;这一点尤其在面试的过程中感受明显。 前两年的时候&#xff0c;面试官有可能问一些比较简单的问题就能通过&#xff0c;今年可就没那么简单了&#xff0c;必须提前做好相关…

SQL的模型类

在Qt的数据库中&#xff0c;除了QSqlQuery访问数据库&#xff0c;还可以使用QSqlQueryModel&#xff0c;QSqlTableModel和QSqlRelationalTableModel&#xff0c;这三个类是从QAbstractTableModel派生下来的&#xff0c;可以很直观的查看数据库的数据 QSqlQueryModel 提供一个…

Educational Codeforces Round 98 (Rated for Div. 2) D. Radio Towers

翻译&#xff1a; 坐标线上有&#x1d45b;2个城镇&#xff0c;编号从0到&#x1d45b;1。&#x1d456;-th镇位于&#x1d456;点。 你在城镇1、2、…、&#x1d45b;以12的概率建造一个无线电塔(这些事件是独立的)。之后&#xff0c;您希望将每个塔上的信号功率设置为从1到…

C/C++开发工具CLion v2022.3全新发布——支持C++ 20

CLion是一款专为开发C及C所设计的跨平台IDE。它是以IntelliJ为基础设计的&#xff0c;包含了许多智能功能来提高开发人员的生产力。这种强大的IDE帮助开发人员在Linux、OS X和Windows上来开发C/C&#xff0c;同时它还使用智能编辑器来提高代码质量、自动代码重构并且深度整合CM…

C++ 当基类为抽象类时如何析构派生类

前言&#xff1a;本教程不涉及基础&#xff0c;稍微了解一下Cvirtual多态的知识就可以了&#xff0c;不了解的话可以先去看一下菜鸟教程&#xff0c;也可以看我往期的文章《virtual》、《虚函数表》 多态分为静态多态和动态多态 静态多态&#xff1a;也成为编译时的多态&#…

使用Word模板导出Word后,表格后面产生空白页

目录 背景 解决 参考 背景 项目中有导出Word功能,其实现逻辑是先整理一个Word文档,里面使用占位符;代码读取Word文档,然后替换占位符。 但出现这样的问题:填充某个表格后,表格后面出现了空白页。 解决 调查发现是段落标记导致的,如何显示段落标记?File -> Op…

生成对抗:DCGAN

DCGAN简介 Generative Adversarial Networks(GANs),GANs有两个模型组成,一个是生成器,用于训练生成假的数据,另一个是判别器,用于预测生成器的输出结果。其中生成器提供训练数据给判别器&#xff0c;提高判别器的准确率。判别器提供生成样本的预测结果&#xff0c;给生成器提供…

【Java系列】小小练习——带你回顾Java基本运算符

返回主篇章         &#x1f447; 【Java】才疏学浅小石Java问道之路 Java小练习1. 练习一1.1 题目1.2 题解(附解析)2. 练习二2.1 题目2.2 题解(附解析)3. 练习三3.1 题目3.2 题解(附解析)小结1. 练习一 1.1 题目 一个三位数&#xff0c;将其拆分为个位、十位、百位后…

mac安装cocoapods完整步骤

一、概念理解 首先不要急着搜索终端命令&#xff0c;你需要明白安装 cocoapods 都需要什么环境&#xff0c;这对于安装途中如果遇到问题该如何解决很重要&#xff0c;很重要&#xff0c;很重要&#xff01; 1、安装pods需要依赖 ruby 环境&#xff0c;而安装 ruby 你需要借助工…

[网鼎杯 2020 白虎组]PicDown(任意文件读取)

打开界面发现有一个get传参然后&#xff0c;尝试任意文件读取漏洞&#xff0c;/etc/passwd看一下,提示下载了一个jpg图片然后 打不开只能用 010查看一下信息 看来是猜对了&#xff0c;然后 如果日记没删掉可以查看历史记录 .bash_history呃呃呃差不到&#xff0c;那就看一下现…

Python 现代控制理论 —— 梯度下降法实现的线性回归系统

线性回归是有监督学习中的经典问题&#xff0c;其核心在于找到样本的多个特征与标签值之间的线性关系。样本集中的第j个样本可被表示为&#xff1a; 特征向量&#xff1a;标签值&#xff1a; 而线性回归系统给出权重向量&#xff1a; 使得该样本的预测值为&#xff1a; 当所有…

Python采集某网站m3u8内容,美女我来了~

前言 嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 又到了学Python时刻~ 环境使用: Python 3.8 Pycharm 模块使用: import requests >>> pip install requests import re 正则表达式 解析数据 import json 安装python第三方模块: win R 输入 cmd 点击确…

不止一面的百变 ACE

这个时代&#xff0c;可谓是云原生的黄金时代。 站在这个云原生的风口&#xff0c;年轻一代的开发者如何看待自己所处的环境&#xff1f;他们眼中的云原生未来是什么样&#xff1f; 今天我们就将走近一位年轻的“云原生原住民”&#xff0c;听听他作为开发者的成长经历。 War…

【python3】9.python高阶内容(上)_基础

9.python高阶内容&#xff08;上&#xff09;_基础 2022.12.27 python高阶内容&#xff08;上&#xff09;_基础9.1 字符串的高阶玩法 9.1.1 %百分号模式 %d:整数%i:整数%s:字符%f:小数 【方式1】&#xff1a;前面用格式占位&#xff0c;后面用具体的内容 name "莫烦…