`

分治法解决数据最大子段和的问题

 
阅读更多

有这么一段数据:int nums[] = {-8, 11, -4, 13, -9, -10};要求求出其中最大子段和,即其中某一连续的几个数据之和最大值,比如这段数据,显然是11+(-4)+13=20为答案。

使用C程序实现的算法,属于分治法。思路是:从中间划开,下标0~5,中间位置(0+5)/2(整除) = 2,那么取0~2,3~5两段下标,递归求最大子段和,用这两个最大字段和,同从2下标开始往左累加,往右累加的最大值,三者比较,取最大值即是最终解。

分治法解决这个问题的根本在于利用递归,实现了从数组的所有下标为标准往两边累加找最大累加值。找出所有情况下的最大累加值就是答案。

 

#include <stdio.h>

int maxSubValues(int nums[], int minIndex, int maxIndex) {
	int sum = 0;
	int allMax = 0;
	int leftMax = 0;
	int rightMax = 0;
	int middleIndex = (minIndex + maxIndex) / 2;
	int i;
	if (minIndex == maxIndex) { // 数组就一个元素了
		if (nums[minIndex] < 0) { // 最大子段有个规定,如果数据都是负数,最大子段值为0
			return 0;
		} else {
			return nums[minIndex];
		}
	}
	leftMax = maxSubValues(nums, minIndex, middleIndex);
	rightMax = maxSubValues(nums, middleIndex+1, maxIndex);
	for (i=middleIndex; i>=0; i--) { // 从中点往左累加最大值
		sum += nums[i];
		if (allMax < sum) {
			allMax = sum;
		}
	}
	sum = allMax; // 保留最大值
	for (i=middleIndex+1; i <= maxIndex; i++) {
		sum += nums[i]; // 往左累加最大值继续累加,找到左右累加最大值
		if (allMax < sum) {
			allMax = sum;
		}
	}
	// 比较左侧最大子段和右侧最大子段还有中间往两边累加的最大值看看谁更大
	if (allMax < leftMax) {
		allMax = leftMax;
	} else if (allMax < rightMax) {
		allMax = rightMax;
	}
	return allMax;
}

int main(int argc, char **argv) {
	int nums[] = {-8, 11, -4, 13, -9, -10};
	printf("max sub:%d\n", maxSubValues(nums, 0, sizeof nums / sizeof(int) - 1));
	return 0;
}

 

分享到:
评论

相关推荐

    最大子段和(分治法)源码

    8. 重要性:最大子段和问题是一个经典的问题,解决该问题需要使用递归算法和分治法,这些技术在数据结构和算法设计中非常重要。 9. 应用场景:最大子段和问题有很多实际应用场景,如计算机视觉、图像处理、数据挖掘...

    最大子段和问题 蛮力法 分治法 动态规划法

    在实际编程中,动态规划法是解决最大子段和问题的首选方法,因为它兼顾了正确性和效率。而蛮力法尽管简单,但在大规模数据面前显得力不从心。至于分治法,由于该问题的特性,它在此处并不适用。 在学习和理解这些...

    算法设计 C 最大子段和 动态规划法和分治法

    本文将深入探讨如何使用C语言实现最大子段和问题,以及如何运用动态规划法和分治法这两种高效策略来解决这一问题。 最大子段和(Maximum Subarray Problem)是计算数组中连续子数组的最大和的经典问题。在实际应用...

    最大子段和-分治法

    通过上述分析,我们可以看到分治法是一种非常有效的解决最大子段和问题的方法。它不仅简洁明了,而且效率高,特别是在处理大规模数据时优势更为明显。理解分治法的基本思想及其在具体问题中的应用对于提升编程能力至...

    设计算法解决最大子段和或棋盘覆盖问题

    在最大子段和问题中,虽然Kadane's Algorithm没有直接使用分治法,但可以通过稍加修改实现分治版本。例如,我们可以将序列分为两半,分别找到左半部分和右半部分的最大子段和,然后考虑跨越分割点的子段。这需要在...

    蛮力法解决最大子段和问题源代码

    本篇将详细探讨通过蛮力法解决最大子段和问题,并结合王红梅的《算法设计与分析》中的第六章实验项目进行讲解。 首先,让我们理解“蛮力法”(Brute Force)的概念。这是一种最直观、最简单的解决问题的方法,通常...

    最大子段和

    然而,在最大子段和问题中,由于子序列可能跨越数组的边界,直接应用分治策略并不直观,因此分治法在此问题上的应用并不常见,且实现起来相对复杂,效率并不优于动态规划。 动态规划(DP)是解决此问题最常用且效率...

    最大子段和问题程序源码

    解决最大子段和问题的经典算法称为Kadane's algorithm(卡丹算法)。这个算法的核心思想是在遍历数组的过程中,维护两个变量:当前子序列的最大和以及全局最大和。在遍历过程中,如果当前元素加上当前子序列的和大于...

    蛮力法分治法动态规划法求最大子段和

    在IT领域,尤其是在算法设计与分析中,求解最大子段和问题是一个经典的问题,它不仅考验了程序员的基础算法知识,还涉及到了多种算法思想的应用,包括蛮力法、分治法以及动态规划法。下面将针对这三种方法进行详细的...

    Maxsum.zip_max sum_max-sum算法_分治法_最大子段和_蛮力法

    总结来说,"Maxsum.zip"的文件内容涵盖了最大子段和问题的三个重要解冑途径:蛮力法、分治法(尽管在本问题中不是主要应用)和动态规划法。这些方法在算法设计和分析中都占有重要地位,理解和掌握它们对于提升编程...

    最大子段和/三种方法/c++

    虽然分治法通常不直接用于解决最大子段和问题,但在某些特定情况下,如处理二维数组时,可以结合分治策略优化问题。在一维数组上,分治法的优势并不明显,因为其时间复杂度仍为O(n^2),与蛮力法相当。然而,理解分治...

    最大子段和问题的三种算法

    在最大子段和问题中,分治法并不直接适用,因为问题的最优解可能跨越子数组的边界。然而,在一些变种问题中,如寻找没有负数的最大子序列和,可以利用分治的思想。例如,E6.5分治法.cpp文件可能实现了一个这样的算法...

    最大子段和问题实验报告.pdf

    【最大子段和问题】是计算机科学中一个经典的问题,主要目标是从一个整数序列中找到连续子序列的最大和。本实验报告详细介绍了三种解决该问题的方法:蛮力法、分治法和动态规划法。 1. **蛮力法**: 蛮力法是最...

    实验4 分治法1

    2. **最大子段和问题**:对于一个整数序列,找到和最大的连续子序列。这个问题可以通过Kadane's algorithm等分治策略解决。 3. **邮局选址问题**:在给定n个居民点的位置后,找到一个点作为邮局的位置,使得所有...

    2022年最大子段和问题实验报告.docx

    综上所述,最大子段和问题可以通过蛮力法、分治法和动态规划法解决,其中动态规划法在时间和空间效率上具有优势。在实际应用中,应根据问题规模和具体需求选择合适的方法。实验的目标不仅是掌握算法,还包括理解算法...

    2022年最大子段和问题实验报告.pdf

    对于最大子段和问题,可以将数组划分为长度相等或相近的两部分,递归地解决左右两部分的最大子段和,然后考虑跨越中间点的最大子段和。如果中间子序列的和加上左右子序列的和比单个子序列的和大,就选择前者。分治法...

    快速排序 最大子段和 huffman n后

    最大子段和问题(Maximum Subarray Problem)是线性代数中一个经典的问题,旨在寻找一串数字中的连续子数组,其和最大。这个问题有多种解决方案,包括动态规划的Kadane's Algorithm。该算法在一次遍历数组的过程中,...

    动态规划,数字三角形 最大子段和问题 最长公共子序列

    1. **最大子段和问题**:这是一个经典的动态规划问题,其目标是在一个整数数组中找到连续子数组的最大和。这个问题可以通过 Kadane's Algorithm 来解决。该算法有两种主要策略:始终保持当前子数组的最大和以及在...

    最大子段和详解.docx

    解决最大子段和问题的方法多种多样,下面我们将详细介绍其中几种不同效率的解法。 ##### 2.1 穷举法 穷举法是最直观也是最简单的解决方案之一。其基本思想是通过双重循环遍历所有可能的子区间,并计算这些子区间的...

Global site tag (gtag.js) - Google Analytics