求解向量中连续子向量的最大和

news2024/11/15 0:09:10

开篇

本篇文章旨在求解向量中n个连续子向量的最大和。题目来源是《编程珠玑》第8章《算法设计技术》。

问题描述

输入:具有n个浮点数的向量x;
输出:输入向量的任何连续子向量中的最大和;
例如:输入向量为31,-41,59,26,-53,58,97,-93,-23,84;
那么输出就是从59到97五个数的总和,即:187.

代码实现

简单算法–时间复杂度: O(n^3)

#include <stdio.h>

#define Max(a,b)((a)>(b)?(a):(b))

int main() {
	int nums[10] = { 31,-41,59,26,-53,58,97,-93,-23,84 };

	// 定义连续向量最大值
	int maxsofar = 0;
	for (int i = 0; i < 10; i++) {
		for (int j = 0; j < 10; j++) {
			int sum = 0;
			for (int k = i; k <= j; k++) {
				sum += nums[k];
			}
			maxsofar = Max(maxsofar, sum);
		}
	}

	printf("最大值为%d.\n", maxsofar);
	return 0;
}

在这里插入图片描述

两个平方算法之一–时间复杂度O(n^2)

// 平方算法1---时间复杂度O(n^2)
int maxSubArraySumPro(int *nums, int length) {
	int maxsofar = 0;
	for (int i = 0; i < length;  i++) {
		int sum = 0;
		for (int j = i; j < length; j++) {
			sum += nums[j];
			maxsofar = Max(maxsofar, sum);
		}
	}

	return maxsofar;
}

两个平方算法之二–时间复杂度O(n^2)

// 平方算法2 --- 时间复杂度O(n^2)
int maxSubArraySumProPlus(int *nums, int length) {
	int len = length + 1;

	// 动态分配数组的内存
	int *cumarr = (int *)malloc(len * sizeof(int));

	if (cumarr == NULL) {
		printf("内存分配失败!\n");
		return -1;
	}

	cumarr[0] = 0;
	for (int i = 1; i < len; i++) {
		cumarr[i] = cumarr[i - 1] + nums[i - 1];
	}

	int maxsofar = nums[0];
	for (int i = 0; i < length; i++) {
		for (int j = i; j < length; j++) {
			int sum = cumarr[j+1] - cumarr[i];
			maxsofar = Max(maxsofar, sum);
		}
	}

	free(cumarr);
	return maxsofar;
}

分治算法–时间复杂度:O(logn)

// 分治算法实现 --- 时间复杂度O(logn)
int dnc(int l, int u, int *nums) {
	if (l > u) { // 0元素数组
		return 0;
	}
	if (l == u) { // 1元素数组
		return Max(0, nums[l]);
	}

	int m = (l + u) / 2;
	int lmax = 0; // 左边最大连续数组的和
	int lsum = 0;
	for (int i = m; i >= l; i--) {
		lsum += nums[i];
		lmax = Max(lmax, lsum);
	}

	int rmax = 0;
	int rsum = 0;
	for (int i = m + 1; i <= u; i++) {
		rsum += nums[i];
		rmax = Max(rmax, rsum);
	}

	return MaxT(lmax + rmax, dnc(l, m, nums), dnc(m + 1, u, nums));
}

Kadane’s算法实现–时间复杂度:O(n)

// Kadane's算法实现 --- 时间复杂度O(n)
int maxSubArraySumKadane(int* nums, int length) {
	int maxsofar = nums[0];  // 初始化最大子数组和为数组的第一个元素
	int currmax = nums[0];   // 当前子数组和初始化为数组的第一个元素

	// 从第二个元素开始遍历数组
	for (int i = 1; i < length; i++) {
		// 当前子数组和为当前位置的元素与之前子数组和的和,如果当前元素本身更大,则重新开始一个子数组
		currmax = (nums[i] > currmax + nums[i]) ? nums[i] : currmax + nums[i];

		// 更新最大子数组和
		maxsofar = (currmax > maxsofar) ? currmax : maxsofar;
	}

	return maxsofar;
}

代码总集

#include <stdio.h>
#include <stdlib.h>

#define Max(a,b)((a)>(b)?(a):(b))

// 辅助函数:返回三个数中的最大值
int MaxT(int a, int b, int c) {
	int maxab = (a > b) ? a : b;
	return (maxab > c) ? maxab : c;
}


// 简单算法--时间复杂度O(n^3)
int maxSubArraySum(int nums[], int length) {
	// 定义连续向量最大值
	int maxsofar = 0;
	for (int i = 0; i < length; i++) {
		for (int j = 0; j < length; j++) {
			int sum = 0;
			for (int k = i; k <= j; k++) {
				sum += nums[k];
			}
			maxsofar = Max(maxsofar, sum);
		}
	}

	return maxsofar;
}

// 平方算法1---时间复杂度O(n^2)
int maxSubArraySumPro(int *nums, int length) {
	int maxsofar = 0;
	for (int i = 0; i < length;  i++) {
		int sum = 0;
		for (int j = i; j < length; j++) {
			sum += nums[j];
			maxsofar = Max(maxsofar, sum);
		}
	}

	return maxsofar;
}

// 平方算法2 --- 时间复杂度O(n^2)
int maxSubArraySumProPlus(int *nums, int length) {
	int len = length + 1;

	// 动态分配数组的内存
	int *cumarr = (int *)malloc(len * sizeof(int));

	if (cumarr == NULL) {
		printf("内存分配失败!\n");
		return -1;
	}

	cumarr[0] = 0;
	for (int i = 1; i < len; i++) {
		cumarr[i] = cumarr[i - 1] + nums[i - 1];
	}

	int maxsofar = nums[0];
	for (int i = 0; i < length; i++) {
		for (int j = i; j < length; j++) {
			int sum = cumarr[j+1] - cumarr[i];
			maxsofar = Max(maxsofar, sum);
		}
	}

	free(cumarr);
	return maxsofar;
}

// Kadane's算法实现 --- 时间复杂度O(n)
int maxSubArraySumKadane(int* nums, int length) {
	int maxsofar = nums[0];  // 初始化最大子数组和为数组的第一个元素
	int currmax = nums[0];   // 当前子数组和初始化为数组的第一个元素

	// 从第二个元素开始遍历数组
	for (int i = 1; i < length; i++) {
		// 当前子数组和为当前位置的元素与之前子数组和的和,如果当前元素本身更大,则重新开始一个子数组
		currmax = Max(nums[i], currmax + nums[i]);

		// 更新最大子数组和
		maxsofar = Max(currmax, maxsofar);
	}

	return maxsofar;
}

// 分治算法实现 --- 时间复杂度O(logn)
int dnc(int l, int u, int *nums) {
	if (l > u) { // 0元素数组
		return 0;
	}
	if (l == u) { // 1元素数组
		return Max(0, nums[l]);
	}

	int m = (l + u) / 2;
	int lmax = 0; // 左边最大连续数组的和
	int lsum = 0;
	for (int i = m; i >= l; i--) {
		lsum += nums[i];
		lmax = Max(lmax, lsum);
	}

	int rmax = 0;
	int rsum = 0;
	for (int i = m + 1; i <= u; i++) {
		rsum += nums[i];
		rmax = Max(rmax, rsum);
	}

	return MaxT(lmax + rmax, dnc(l, m, nums), dnc(m + 1, u, nums));
}

int main() {
	int nums[10] = { 31,-41,59,26,-53,58,97,-93,-23,84 };

	int maxSum = maxSubArraySumKadane(nums, 10);
	// int maxSum = dnc(0, 9, nums);

	printf("最大值为%d.\n", maxSum);
	return 0;
}

上面的代码总体来说比较简单,此处就不过多解释了。值得一提的是,题目中要求的是浮点型,而我用的是int类型,这个是我实现的过程中的疏漏,还请谅解了。
希望本文对您能有所帮助,感谢阅读。

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

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

相关文章

基于java+springboot+mysql校园预约自习室网站43642-计算机毕业设计项目选题推荐(免费领源码)

摘要 在社会快速发展的影响下&#xff0c;教育事业蓬勃发展&#xff0c;大大增加了学校的数量、多样性、教育质量等要求&#xff0c;使教育的管理和运营比过去更加困难。依照这一现实为基础&#xff0c;设计一个快捷而又方便的校园预约自习室网站是一项十分重要并且有价值的事情…

回归预测|基于北方苍鹰优化最小二乘支持向量机的数据预测Matlab程序NGO-LSSVM 多特征输入单输出 含基础程序

回归预测|基于北方苍鹰优化最小二乘支持向量机的数据预测Matlab程序NGO-LSSVM 多特征输入单输出 含基础程序 文章目录 前言回归预测|基于北方苍鹰优化最小二乘支持向量机的数据预测Matlab程序NGO-LSSVM 多特征输入单输出 含基础程序 一、NGO-LSSVM模型1. LSSVM&#xff08;最小…

联网可视化:引领智能出行新时代

图扑车联网可视化系统整合数据监测与分析&#xff0c;提升交通管理效率&#xff0c;优化车辆调度&#xff0c;提高道路安全&#xff0c;为用户提供智能化、便捷的出行体验。

使用Python实现方波信号傅里叶变换

目录 概述 1 方波信号 1.1 问题描述 1.2 傅里叶级数的数学实现 2 函数实现 2.1 方波信号实现 2.2 方波信号的傅里叶函数 3 测试函数 3.1 测试原理 3.2 改变K值的波形变化 概述 本文主要介绍使用使用Python实现方波信号傅里叶变换的方法&#xff0c;笔者首先介绍了方…

如何使用ssm实现基于java的奶茶店管理系统的设计与实现

TOC ssm140基于java的奶茶店管理系统的设计与实现jsp 第一章 绪 论 1.1背景及意义 系统管理也都将通过计算机进行整体智能化操作&#xff0c;对于奶茶店管理系统所牵扯的管理及数据保存都是非常多的&#xff0c;例如管理员&#xff1b;主页、个人中心、用户管理、奶茶分类管…

Kubectl基础命令使用

一.Kubectl 基础命令 格式&#xff1a; kubectl [command] [TYPE] [NAME] [FLAGS] kubectl 是 Kubernetes 的命令行工具&#xff0c;用于管理 Kubernetes 集群。以下是一些常用的 kubectl 命令及其选项&#xff1a; 常用命令 获取资源 列出所有资源类型&#xff08;Pods、De…

【C++】OJ习题 篇1

&#x1f680;个人主页&#xff1a;奋斗的小羊 &#x1f680;所属专栏&#xff1a;C 很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~ 目录 &#x1f4a5;1、string&#x1f4a5;1.1 字符串相加&#x1f4a5;1.2 验证回文字符串&#x1f4a5;1.3 反转…

【奇某信-注册/登录安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞…

(论文解读)Domain Adaptation via Prompt Learning

摘要 无监督域适应( UDA )旨在将从带有标签的源域数据中学习到的模型适应到未标注的目标域数据集。现有的UDA方法通过对齐源域和目标域特征空间来学习领域不变特征。这种对齐是通过约束实现的&#xff0c;例如统计差异最小化或对抗学习。 然而&#xff0c;这些约束会导致语义…

【自动驾驶】控制算法(四)坐标变换与横向误差微分方程

写在前面&#xff1a; &#x1f31f; 欢迎光临 清流君 的博客小天地&#xff0c;这里是我分享技术与心得的温馨角落。&#x1f4dd; 个人主页&#xff1a;清流君_CSDN博客&#xff0c;期待与您一同探索 移动机器人 领域的无限可能。 &#x1f50d; 本文系 清流君 原创之作&…

浙大版循环结构程序设计 7-6-1 贪心法-找零钱

7-6-1 贪心法-找零钱 #include <stdio.h>int main(){int n5,n2,n1,money,total;int flag 1; //判断是否符合条件然后跳出循环scanf("%d",&money);if(money>100){printf("Invalid.");}for(n5money/5;(flag1)&&(n5>0);n5--){for(n2…

2-75 基于matlab的多尺度小波核svm预测

基于matlab的多尺度小波核svm预测&#xff0c;数据归一化操作&#xff0c;尺度小波核函数作为核函数进行训练&#xff0c;训练后的模型进行预测。程序已调通&#xff0c;可直接运行。 2-75 多尺度小波核 SVM预测 - 小红书 (xiaohongshu.com)

Java 认识String类

1. 创建字符串 常见的构造 String 的方式 //方式一&#xff1a;String str "hello world";//方式二&#xff1a;String str2 new String("Hello world");//方式三&#xff1a;char[] array {a,b,c};String str3 new String(array);注意事项&#xff1…

Promise学习之初步认识Promise

目录 前言 一、认识Promise (一) 含义 (二) 代码演示 二、Promise状态 三、总结 前言 在上一篇的学习中&#xff0c;我们已经认识到了同步与异步&#xff0c;异步代码在解决同步代码问题的同时&#xff0c;也会产生一些新的问题&#xff0c;比如常说的回调地狱&#xff0…

DBSCAN算法及Python实践

DBSCAN&#xff08;Density-Based Spatial Clustering of Applications with Noise&#xff0c;具有噪声的基于密度的空间聚类应用&#xff09;算法是一种基于密度的聚类算法&#xff0c;它在机器学习和数据挖掘领域有广泛的应用。以下是DBSCAN算法的主要原理和特点&#xff1a…

系统编程-管道

管道 目录 管道 1、管道的特点 2、无名管道的使用步骤 &#xff08;1&#xff09;在进程中使用 pipe 函数来获取管道的文件描述符 &#xff08;2&#xff09;使用 fork 函数来创建子进程 &#xff08;3&#xff09;通过获取到的文件描述符来进行数据的传输 &#xff08…

第八周:机器学习

目录 摘要 Abstract 一、注意力机制V.S.自注意力机制 1、引入 2、注意力机制 3、自注意力机制 二、自注意力机制 1、输入 2、输出 3、序列标注 4、Multi-head Self-attention 5、比较 总结 摘要 前两周学习了CNN的基本架构&#xff0c;针对全局信息的考虑问题&…

【Kotlin设计模式】Kotlin实现单例模式

前言 单例模式&#xff08;Singleton Pattern&#xff09;&#xff0c;是确保一个类只有一个实例&#xff0c;并提供一个全局访问点来访问这个实例。在 Android 中&#xff0c;有许多系统服务和 API 使用了单例模式&#xff0c;比如&#xff1a; Context: 通过getApplication…

SpringBoot2:创建项目及启动时相关报错整理

1、创建时报错 Initialization failed for https://start.aliyun.com/ Please check URL, network and proxy settings.Error message: Error parsing JSON response换官网地址初始化即可&#xff1a;https://start.spring.io/ 那么&#xff0c;大家肯定会疑问&#xff0c;官网…

【SpringBoot】10 日志持久化(log4j2)

介绍 日志概念 日志是系统生成的数据&#xff0c;用于记录网络、端点、物联网、应用程序、操作系统等&#xff0c;在运行时所发生事件的信息&#xff0c;便于开发人员或维护人员进行故障排查、性能优化、安全审计等工作。 日志作用 问题追踪及调试&#xff1a;当程序出现问…