【数据结构与算法】Kadane‘s算法(动态规划、最大子数组和)

news2024/11/10 16:23:38

文章目录

  • 一、算法原理
  • 二、例题
    • 2.1 最大子数组和
    • 2.2 环形子数组的最大和

一、算法原理

Kadane's算法是一种用于解决最大子数组和问题的动态规划算法。这类问题的目标是在给定整数数组中找到一个连续的子数组,使其元素之和最大(数组含有负数)。

算法的核心思想是通过迭代数组的每个元素,维护两个变量来跟踪局部最优解和全局最优解。

以下是Kadane’s算法的详细步骤:

  1. 初始化:

    • 令 maxEndingHere 表示在当前位置结束的最大子数组和,初始值为数组的第一个元素。
    • 令 maxSoFar 表示全局最大子数组和,初始值也为数组的第一个元素。
  2. 迭代:

    • 从数组的第二个元素开始迭代。

    • 对于每个元素,计算在当前位置结束的最大子数组和:
      maxEndingHere = max(nums[i], maxEndingHere + nums[i]);
      这表示要么继续当前子数组,要么从当前位置开始一个新的子数组。

    • 更新全局最大子数组和:
      maxSoFar = max(maxSoFar, maxEndingHere);
      如果在当前位置结束的子数组和大于全局最大和,更新全局最大和。

  3. 返回结果:

    • 当迭代完成后,maxSoFar 中存储的即为最大子数组和。

复杂度:

  • 时间复杂度:O(n),其中 n 为 nums 数组的长度。我们只需要遍历一遍数组即可求得答案。
  • 空间复杂度:O(1)。我们只需要常数空间存放若干变量。

图例:
在这里插入图片描述

简要说明:(如过当前值比前面的局部最大值+当前值还大,那么就从当前值开始继续计算局部最大值)

  1. i=0,maxEndingHere 、maxSoFar 初始值都为数组第一个元素,-2;
  2. 开始循环,i=1,maxEndingHere = max(nums[1], maxEndingHere + nums[1]),即maxEndingHere = max(1, -2 + 1)=1,maxSoFar=1;
  3. i=2, maxEndingHere = max(nums[2], maxEndingHere + nums[2]),即maxEndingHere = max(-3, 1 - 3)=-2,maxSoFar=1;
  4. i=3,maxEndingHere = max(nums[3], maxEndingHere + nums[3]),即maxEndingHere = max(4, -2 + 4)=4,maxSoFar=4;

二、例题

2.1 最大子数组和

在这里插入图片描述

解答:

int maxSubArray(int* nums, int numsSize) {
    int maxEndingHere  = nums[0], maxSoFar = nums[0];
    for (int i = 1; i < numsSize; i++) {
        maxEndingHere  = fmax(maxEndingHere  + nums[i], nums[i]);
        maxSoFar = fmax(maxSoFar, maxEndingHere );
    }
    return maxSoFar;
}

fmax是<math.h>中的函数,用于比较2个数字的大小,双精度。

简单换个写法:

int maxSubArray(int* nums, int numsSize) {
    int maxEndingHere  = nums[0], maxSoFar = nums[0];
    for (int i = 1; i < numsSize; i++) {
        maxEndingHere  = maxEndingHere  + nums[i]>nums[i]?maxEndingHere  + nums[i]:nums[i];
        maxSoFar = maxSoFar>maxEndingHere?maxSoFar:maxEndingHere;
    }
    return maxSoFar;
}

简单用三目表达式代替fmax函数。

2.2 环形子数组的最大和

在这里插入图片描述

解答:

int maxSubarraySumCircular(int* nums, int numsSize) {
    if (nums == NULL || numsSize == 0) return 0;
    int maxSum = nums[0], minSum = nums[0];
    int maxCur = nums[0], minCur = nums[0];
    int sum = nums[0];

    for (int i = 1; i < numsSize; i++) {
        sum += nums[i];
        maxCur = fmax(nums[i], maxCur + nums[i]);
        minCur = fmin(nums[i], minCur + nums[i]);
        maxSum = fmax(maxSum, maxCur);
        minSum = fmin(minSum, minCur);
    }

    if (maxSum < 0) return maxSum; // 如果所有数都是负数,返回最大值
    return fmax(maxSum, sum - minSum); // 返回“不跨越头尾的最大子数组和”和“跨越头尾的最大子数组和”中的较大者
}

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

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

相关文章

采集1688整店商品(店铺所有商品、店铺列表api)

返回数据&#xff1a; 请求链接 {"user": [],"items": {"item": [{"num_iid": "738354436678","title": "国产正品i13 promax全网通5G安卓智能手机源头厂家批发手机","pic_url": "http…

elementui表格自定义指令控制显示哪些列可以拖动

Vue.directive(tableBorder, function (el, {value}) {// value允许传字符串数字和数组el.classList.add(z_table_hasBorder)let hasStyle el.querySelector(style)if(hasStyle){hasStyle.remove()}let style document.createElement(style)let str .z_table_hasBorder .el…

基于ResNet框架的CNN

数据准备 DATA_URL http://download.tensorflow.org/example_images/flower_photos.tgz 一、训练集和验证集的划分 #spile_data.pyimport os from shutil import copy import randomdef mkfile(file):if not os.path.exists(file):os.makedirs(file)file flower_data/flower…

代码随想录算法训练营第四十九天| 123.买卖股票的最佳时机III 188.买卖股票的最佳时机IV

文档讲解&#xff1a;代码随想录 视频讲解&#xff1a;代码随想录B站账号 状态&#xff1a;看了视频题解和文章解析后做出来了 123.买卖股票的最佳时机III class Solution:def maxProfit(self, prices: List[int]) -> int:if len(prices) 0:return 0dp [[0] * 5 for _ in…

【监控系统】日志可视化监控体系ELK搭建

1.ELK架构是什么 ELK是ElasticsearchLogstashKibana的简称。 Elasticsearch是一个开源的分布式搜索和分析引擎&#xff0c;可以用于全文检索、结构化检索和分析&#xff0c;它构建在Lucene搜索引擎库之上&#xff0c;是当前使用较为广泛的开源搜索引擎之一。 Logstash是一个…

Linux从 全栈开发 centOS 7 到 运维

Linux从 全栈开发centOS 7 到 运维 一 Linux 入门概述1.1 操作系统1.2 Linux 简介1.3 Linux 系统组成1.4 Linux 发行版1.4 Linux 应用领域1.5 Linux vs Windows 二 环境搭建【狂神说Java】服务器购买及宝塔部署环境说明为什么程序员都需要一个自己的服务器服务器如何购买买完服…

gitlab利用CI多工程持续构建

搭建CI的过程中有多个工程的时候&#xff0c;一个完美的构建过程往往是子工程上的更新(push 或者是merge)触发父工程的构建&#xff0c;这就需要如下建立一个downstream pipeline 子仓库1 .gitlab-ci.yml stages:- buildbuild_job:stage: buildtrigger:project: test_user/tes…

远程文件包含演示

远程文件包含 基本介绍 受害机器 10.9.47.181 攻击者机器1 10.9.47.41 攻击者机器2 10.9.47.217 实现过程 受害者机器开启phpstudy 并且开启允许远程连接 攻击者机器1上有一个文件&#xff0c;内容是phpinfo(); 攻击者机器1提供web服务使得受害者机器能够访问到攻击者…

APP源码|智慧校园电子班牌源码 智慧校园云平台

智慧校园云平台电子班牌系统包括&#xff1a;智慧校园信息管理平台、saas后台管理平台、微信客户端平台、智慧班牌智能终端软件。主要用于构建学校基础架构&#xff0c;进行成员管理、权限分配以及运营数据监管等&#xff0c;是“智慧校园”的“根基”&#xff0c;是各项应用和…

buildadmin+tp8表格操作(8) 表格下方添加 合计行

表格的下方可以自定义添加一个合计行&#xff0c;如果有其它的需求&#xff0c; 我们可以添加我们自已需要的行&#xff0c; 并不局限于合计行 以上就可以给表格的最下方添加一个合计行了 完整代码如下 <template><div class"default-main ba-table-box"&…

python 就是随便玩玩,生成gif图,生成汉字图片,超级简单

文章目录 主方法调用LetterDrawingWordDoingImage 上图 你也想玩的话&#xff0c;可以直接上码云去看 码云链接 主方法调用 import analysisdata.WordDoingImage as WordDoingImage import analysisdata.LetterDrawing as LetterDrawingif __name__ __main__:# 输入的文本&a…

矩阵理论——Gerschgorin定理,以及用python绘制Gerschgorin圆盘动图

矩阵理论——Gerschgorin定理&#xff0c;以及用python绘制Gerschgorin圆盘动图 在矩阵的特征值估计理论当中&#xff0c;有一节是盖尔圆盘定理&#xff1a; 对于一个n阶复数矩阵A&#xff0c;每个特征值lambda位于至少一个Gerschgorin圆盘中&#xff0c;这些圆盘的中心为矩阵…

如何判断sql注入流量特征

如何判断sql注入流量特征 以dvwa的sql注入为例 首先构造一个完整的sql注入请求包 GET /dvwa_2.0.1/vulnerabilities/sqli/?id1&SubmitSubmit HTTP/1.1 Host: 10.9.47.41 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/119.…

vue3+vite+SQL.js 读取db3文件数据

前言&#xff1a;好久没写博客了&#xff0c;最近一直在忙&#xff0c;没时间梳理。最近遇到一个需求是读取本地SQLite文件&#xff0c;还是花费了点时间才实现&#xff0c;没怎么看到vite方面写这个的文章&#xff0c;现在分享出来完整流程。 1.pnpm下载SQL.js(什么都可以下)…

SAP 通过游标来分批从数据库表读取2G数据

原文链接&#xff1a;https://blog.csdn.net/Buffalo_soldier/article/details/109772612 我们在写程序的时候可能会遇到用内表处理超大量数据的情况&#xff0c;比如取MSEG、BSEG表&#xff0c;内表里的数据如果超过2G就会报程序dump了&#xff0c;所以关键是要控制内表的数据…

【Spring Boot】使用WebSocket协议完成来单提醒及客户催单功能

1 WebSocket介绍 WebSocket 是基于 TCP 的一种新的网络协议。它实现了浏览器与服务器全双工通信(双向传输)——浏览器和服务器只需要完成一次握手&#xff0c;两者之间就可以创建持久性的连接&#xff0c; 并进行双向数据传输。 1.1 HTTP协议和WebSocket协议对比 1、HTTP是短…

【FFmpeg实战】ffmpeg播放器-音视频解码流程

音视频介绍 音视频解码流程 FFmpeg解码的数据结构说明 AVFormatContext&#xff1a;封装格式上下文结构体,全局结构体,保存了视频文件封装格式相关信息AVInputFormat&#xff1a;每种封装格式&#xff0c;对应一个该结构体AVStream[0]&#xff1a;视频文件中每个视频&#xff…

Java —— 抽象类和接口

目录 1. 抽象类 1.1 抽象类概念 1.2 抽象类语法与特性 1.3 抽象类的作用 2. 接口 2.1 接口的概念 2.2 接口的语法规则与特性 2.3 实现多个接口(解决多继承的问题) 2.4 接口间的继承 2.5 抽象类和接口的区别 2.6 接口的使用实例 2.7 Clonable 接口和深拷贝 2.7.1 Cloneable接口 …

【自动驾驶解决方案】C++取整与保留小数位

一、C基础 1.1double型保留小数为&#xff0c;并以字符输出 #include <iostream> #include <sstream> #include <iomanip> // 包含std::fixedint main() {//浮点数double number 3.1415926;//转换工具类streamstd::stringstream stream;stream << s…

【考研】数据结构(更新到顺序表)

线性表的定义和基本操作 学习目标 线性表定义&#xff1a;具有相同数据类型的n个数据元素的有序序列。 顺序表定义&#xff1a; 特点 基本操作 定义 静态&#xff1a; #include<stdio.h> #include<stdlib.h>#define MaxSize 10//静态 typedef struct{int …