求出最大连续子序列和 暴力算法、分治法、动态规划、贪心算法实现;Leecode 51.最大子序和

2023-11-04

求出最大连续子序列和

【问题描述】
给定一个整数数组 a[ ] ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

这个问题也可转入Leecode 51.最大子序和
来源:力扣(LeetCode)

示例:
输入: [-2,1,-3,4,-1,2,1,-5,4],
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。

以下用四种方法实现

①蛮力法(即暴力算法)实现:
在这里插入图片描述
代码实现:

int maxSubSum1(int a[],int n){
	int i,j,k;
	int maxSum=0,thisSum;
	for(i=0;i<n;i++){
		for(j=i;j<n;j++){
			thisSum=0;
			for(k=i;k<=j;k++)
			thisSum+=a[k];
			if(thisSum>maxSum)
			maxSum=thisSum;
		}
	}
	return maxSum;
}

算法复杂度T(n)=O(n^3)

解法2:
改进前面的解法,在求两个相邻子序列和的时候,它们之间是关联的。
例如a[0…3]子序列和=a[0]+a[1]+a[2]+a[3],a[0…4]子序列和=a[0]+a[1]+a[2]+a[3]+a[4]
在前者计算出来后,求后者时只需在前者的基础上加上a[4]即可,没有必须每次都重复计算。
从而提高算法效率。

代码实现:

int maxSbuSum2(int a[],int n) {
	int i,j;
	int maxSum=0,thisSum;
	for(i=0;i<n;i++){
		thisSum=0;
		for(j=i;i<n;j++){
			thisSum+=a[i];
			if(thisSum>maxSum)
			maxSum=thisSum;
		}
	}
	return maxSum;
}

时间复杂度T(n)=O(n^2)

解法3:更进一步改进解法2
如果扫描中遇到了负数,当前子序列和thisSum将会减小,若thisSum为负数,表明
前面已经扫描的那个子序列可以抛弃了,则放弃这个子序列,重新开始下一个子序
列的分析,并置thisSum为0
若这个子序列和thisSum不断增加,那么最大子序列和maxSumy也不断增加。

int maxSubSum(int a[],int n){
	int j,maxSum=0,thisSum=0;
	for(j=0;j<n;j++){
		thisSum+=a[j];
		if(thisSum<0)
		thisSum=0;
		if(maxSum<thisSum)
		maxSum=thisSum;
	}
	return maxSum;
}

②分治算法实现
【问题求解】
对于含有n个整数的序列a[0…n-1],若n=1,表示该序列只含有1个元素,如果该元素大于0,则反汇该元素,否则返回0.

若n>1,采用分治法求解最大连续子序列时取其中中间位置mid=(n-1)/2向下取整,该子序列只可能出现在3个地方如下图所示

(1)该子序列完全在左半部分即a[0…mid]中采用递归求其最大连续子序列和maxLeftSum.

(2)该子序列完全落在右半部分,即a[mid+1…n-1]中,采用递归求出其最大连续子序列和maxRightSum

(3)该子序列跨越序列a的中部而占据左、右两部分。
在这里插入图片描述
代码实现:

#include<stdio.h>
int n=6;
int a[]={0,-2,11,-4,13,-5,-2}; 
int max(long a,long b,long c){  //求出a,b,c三者中的最大值 
	if(a<b) a=b;
	if(a>c) return a;
	else return c;
}
int maxSubArray(int left,int right)
{
        int i,j;
		int maxLeftSum,maxRightSum;
	    int maxLeftBorderSum,leftBorderSum;
		int maxRightBorderSum,rightBorderSum;
		if(left==right){  //当子序列只有一个元素时 
			if(a[left]>0)  //元素大于0的时候返回它 
			return a[left];
			else return 0;  //小于或等于0的时候返回0 
		}
		int mid=(left+right)/2;
		maxLeftSum=maxSubArray(left,mid);  //求左边的最大连续子序列的和 
		maxRightSum=maxSubArray(mid+1,right);  //求右边的最大连续子序列之和 
		maxLeftBorderSum=0,leftBorderSum=0;
		for(i=mid;i>=left;i--){  //求出以左边加上a[mid]元素构成的序列的最大和 
			leftBorderSum+=a[i];
			if(leftBorderSum>maxLeftBorderSum)
			maxLeftBorderSum=leftBorderSum;
		}
		maxRightBorderSum=0,rightBorderSum=0;
		for(j=mid+1;j<=right;j++){  //求出a[mid]右边元素构成的序列的最大和
			rightBorderSum+=a[j];
			if(rightBorderSum>maxRightBorderSum)
			maxRightBorderSum=rightBorderSum;
		}
		return max(maxLeftSum,maxRightSum,maxLeftBorderSum+maxRightBorderSum);
}
int main(){
	printf("%d",maxSubArray(0,n));
	return 0;
}

③动态规划算法实现:
dp[i]表示数组a中以a[i]结尾的最大子序列和
状态转移方程如下
dp[0]=0 (边界条件)
dp[i]=max{dp[i-1]+ai,ai} (1<=i<=n)
即dp[i]要么是当前数字要不然是与前面的最大子序和的和。
在这里插入图片描述

代码实现:

#include<iostream>
#include<algorithm>
using namespace std;
int dp[100];
int n=6;
int a[]={0,-2,11,-4,13,-5,-2}; 
int Maxsum()  //求解算法
{
	int result=INT_MIN;
	dp[0]=0;
	result=dp[0];
	for(int j=1;j<=n;j++){
	dp[j]=max(dp[j-1]+a[j],a[j]);
	result=max(result,dp[j]);
	}
	return result;
 } 
 int main(){
	cout<<Maxsum()<<endl;
	return 0;
 }

④贪心算法实现:
对素组从左向右迭代,一个个数字加过去,如果sum<0,重新开始找子序列。
在这里插入图片描述
代码实现:

#include<iostream>
#include<algorithm>
using namespace std;
int n=6;
int a[]={0,-2,11,-4,13,-5,-2}; 
int maxSubArray()
    {
        //因为int占4字节32位,根据二进制编码的规则,INT_MAX = 2^31-1,INT_MIN= -2^31.
		//C/C++中,所有超过该限值的数,都会出现溢出,出现warning,但是并不会出现error
		//INT_MAX = 2^31 - 1 =2147483647,INT_MIN= - 2^31 = -2147483648
        int result = INT_MIN;
        int sum = 0;
        for (int i = 0; i <=n; i++)
        {
            sum += a[i];
            result = max(result, sum);
            //如果sum < 0,重新开始找序列 
            if (sum < 0)
            {
                sum = 0;
            }
        }
        return result;
    }
int main(){
	cout<<maxSubArray()<<endl;
	return 0;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

求出最大连续子序列和 暴力算法、分治法、动态规划、贪心算法实现;Leecode 51.最大子序和 的相关文章

随机推荐

  • Springboot-MDC+logback实现日志追踪

    一 MDC介绍 MDC Mapped Diagnostic Contexts 映射诊断上下文 该特征是logback提供的一种方便在多线程条件下的记录日志的功能 某些应用程序采用多线程的方式来处理多个用户的请求 在一个用户的使用过程中 可能
  • Linux 安装cento

    在虚拟机中安装CentOS7 http www centoscn com image text setup 2014 0723 3341 html CentOS 7 下 ifconfig command not found 解决办法 htt
  • localStorage.setItem()使用

    localStorage setItem 使用
  • python自测100题

    如果你在寻找python工作 那你的面试可能会涉及Python相关的问题 通过对网络资料的收集整理 本文列出了100道python的面试题以及答案 你可以根据需求阅读测试 python基础 Q1 什么是Python Python是一种面向对
  • Scala学习第一天(十三):映射(可变/不可变Map;Map基本操作)

    学习目标 映射 不可变Map 可变Map Map基本操作 映射 Map可以称之为映射 它是由键值对组成的集合 在Scala中 Map也分为 不可变Map 可变Map 不可变Map 语法 val var map Map 键 gt 值 键 gt
  • Spring @ComponentScan 自定义扫描规则

    Spring ComponentScan 组件中扫描规则使用场景 package org example cap2 config import org springframework context annotation Bean impo
  • Apache Beam简介及相关概念

    文章目录 一 简介 二 基本概念 1 Pipelines 2 PCollection 3 Transforms 4 ParDo 5 Pipeline I O 6 Aggregation 7 User defined functions UD
  • H5 手机键盘兼容

    文章目录 键盘弹起页面表现 ios表现 安卓表现 监听软键盘弹起和收起 ios监听focus blur事件 安卓还可见监听页面高度 获取软键盘高度 通过window visualViewport异步获取 唤起软键盘始终让焦点元素滚动到可视区
  • SQL执行计划的十大参数

    调用分析指令分析sql再进行对应的调优 explaion select 十个参数 id 编号 select type 查询类型 table 表 type 索引类型 possible keys 预测可能用到的索引 key 实际使用的索引 ke
  • css实现垂直居中6,CSS实现水平、垂直居中的6种方式

    1 块级元素和行内元素 2 水平居中和垂直居中 3行内元素的水平居中 1 table 2 设置line height 3 text align center 4 margin 0 auto 5 绝对定位 6 flex弹性盒模型 7 calc
  • Http协议、get和post请求整理

    1 什么是GET 和 POST GET 和 POST 其实都是 HTTP 的请求方法 除了这 2 个请求方法之外 HTTP 还有 HEAD PUT DELETE TRACE CONNECT OPTIONS 这 6 个请求方法 所以HTTP的
  • VMware16 Pro的安装及VMware配置CentOS7虚拟机(快照使用)

    VMware16 Pro下载安装 1 进入官网下载 VMware官网 2 选择资源栏目 点击产品下载 3 找到VMware Workstation Pro进行下载 搜索框搜索 vmware workstation 16 pro for wi
  • mysql中双引号和单引号有什么区别

    mysql中双引号和单引号有什么区别 前2天看到有人问 mysql中双引号和单引号有什么区别 希望大家可以关注下公众号 支持一下 鞠躬感谢 我就直接po代码和截图了 如下 select from employees where last n
  • vue3 + vite npm 组件库开发(一)

    1 创建项目 创建一个普通的vite vue3 项目即可 我这里创建的是ts的项目 js也可 根据自己的使用习惯 2 配置项目 根目录下创建packages目录作为组件的开发包 目录下index ts 作为整个组件库的出口文件 导出组件 i
  • “目标检测“+“视觉理解“实现对输入图像的理解

    提出了GLIPv2 一种基于VL的理解模型 它服务于localization任务 例如 目标检测 实例分割 和视觉语言 VL 理解任务 例如 VQA 图像字幕 论文地址 https arxiv org pdf 2206 05836 pdf
  • 如何利用ProcessOn 做资产管理流程图

    资产管理 是一家公司最重要的管理活动 好的资产管理可以让资源最优化利用 实现资产价值的最大化 可以帮助组织管理和降低风险 同时当需要决策的时候 对资产数据进行分析和评估 也可以帮助做出更明智的决策 如优化资产配置 更新技术设备等 一 资产流
  • 笔记24-1(C语言进阶 程序环境和预处理)

    目录 注 推荐书籍 程序的翻译环境和执行环境 编译和链接 翻译环境 编译 预处理 编译 汇编 链接 运行环境 执行环境 注 本笔记参考 B站up 鹏哥C语言 推荐书籍 程序员的自我修养 程序的翻译环境和执行环境 在ANSI C的任何一种实现
  • 可以同情弱者,别同情弱势!

    大家好 我是北妈 0 最近北妈在重刷 天道 里面提到了一个强势文化 弱势文化的概念 我觉得对生活和职场 感情都有些指导作用 我看影评和各种文章讨论这个的概念比较多 毕竟大家都喜欢谈格局 强弱 今天讨论下如何成为强者 强者是不是应该鄙视弱者
  • C++类与对象:初始化列表(赋值和初始化的区别)

    标题 使用初始化列表的情况 初始化与赋值的区别 构造函数体内部是赋值 初始化列表 const成员变量初始化 自定义类型成员初始化 成员变量的缺省值 临时变量 总结 使用初始化列表的情况 成员变量是const类型 成员变量是引用类型 成员变量
  • 求出最大连续子序列和 暴力算法、分治法、动态规划、贪心算法实现;Leecode 51.最大子序和

    求出最大连续子序列和 问题描述 给定一个整数数组 a 找到一个具有最大和的连续子数组 子数组最少包含一个元素 返回其最大和 这个问题也可转入Leecode 51 最大子序和 来源 力扣 LeetCode 示例 输入 2 1 3 4 1 2