Kadence 算法:最大和连续子数组

什么是最大和连续子数组?
子数组是数组的连续部分。它可以是数组的单个元素,也可以是数组的某个部分。最大和连续子数组是指具有最大和值的子数组。
例如,考虑数组 {-10, 5, 1, 6, -9, 2, -7, 3, -5}。它的子数组可以是 {-10, 5, 1, 6}、{5, 1, 6} 或 {2, -7, 3, -5},依此类推。但是,{5, 1, 6, 3} 不能作为子数组,因为其中的元素不是连续的。
如果你仔细观察,会发现所有子数组中,高亮显示的子数组 {5, 1, 6} 的总和值最大:
子数组 {5, 1, 6} 的和为 12,这是上述数组所有可能子数组中的最大和。因此,对于该数组,和最大的连续子数组是 {5, 1, 6}。
求解最大和连续子数组的简单方法
这道题的简单解决方法就是用两次循环找出所有子数组,计算和,然后找到它的最大值。
以下是寻找最大和连续子数组的简单方法的流程图。这是一种穷举法,因为我们需要遍历所有可能的子数组。
以下是执行此操作的简单步骤。
步骤1) 初始化 最大和 最小整数值并设置 开始 和 end 归零。
步骤2) 让 i 和 j 是数组索引,其中 j 大于或等于 i; i 标记子数组的起始位置和 j 它的终结。
步骤3) 当前总和 保存累计总和。每次更新后,检查是否 当前总和 大于 最大和.
步骤4) If 当前总和 如果更大,则替换 最大和 用它。
步骤5) 日期 j 到达数组末尾时,递增 i 并重置 当前总和 到0。
步骤6) 重复直到 i 到达数组末尾。 最大和 然后保存最大的子数组和。
昵称 Code 简易方法
function maximumSubarraySum(): input: array for all possible subArray from array: calculate sum of each subarray store the maximum subArray return the maximum sum
C++ 简单方法的实施
#include <stdio.h> #include <iostream> using namespace std; void maximumSubarraySum(int array[], int n) { int max_sum = -1e9; int begin = 0; int end = 0; for (int i = 0; i < n; i++) { int current_sum = 0; for (int j = i; j < n; j++) { current_sum += array[j]; if (max_sum < current_sum) { max_sum = current_sum; begin = i; end = j; } } } cout << "largest sum is " << max_sum << endl; cout << "largest sum contiguous subarray: "; for (int i = begin; i <= end; i++) { cout << array[i] << "\t"; } } int main() { int array[] = {-10, 5, 1, 6, -9, 2, -7, 3, -5}; maximumSubarraySum(array, sizeof(array) / sizeof(array[0])); }
输出:
largest sum is 12 largest sum contiguous subarray: 5 1 6
Python 简单方法的实施
def maximumSubarraySum(numbers): max_sum, begin, end = -1e9, 0, 0 for i in range(len(numbers)): current_sum = 0 for j in range(i, len(numbers)): current_sum += numbers[j] if max_sum < current_sum: max_sum = current_sum begin, end = i, j print("largest sum is ", max_sum) print("largest sum contiguous subarray: ", end='') for i in range(begin, end + 1): print(numbers[i], end='\t') numbers = [-10, 5, 1, 6, -9, 2, -7, 3, -5] maximumSubarraySum(numbers)
输出:
largest sum is 12 largest sum contiguous subarray: 5 1 6
Kadane算法寻找最大和连续子数组
Kadane 算法是一种动态规划方法,它使用单个循环而不是两个循环。它可以处理包含正数和负数的混合数组,只要至少有一个值是非负数即可。
我们只需要两个变量就能找到最大的连续子数组和。流程图如下:
以下是 Kadane 算法的步骤:
步骤1) 创建两个变量, 当前总和 和 最大和.
当前总和 保留以特定数组索引结尾的最大和,而 最大和 存储目前为止观察到的最大总和值。
步骤2) 将每个数组元素添加到 当前总和然后检查以下两个条件:
- If 当前总和 如果小于当前元素,则 当前总和 成为当前元素。
- If 最大和 小于 当前总和, 然后 最大和 成为 当前总和.
步骤3) 对整个数组重复上一步后, 最大和 包含最大的连续子数组总和。
Kadane 算法的示例
我们用一个小数组演示 Kadane 算法,并逐步讲解如何找到最大和连续子数组。
假设给定的数组如下所示:
以下是卡丹算法的步骤:
步骤1) 创建两个变量, 当前总和 和 最大和将 INT_MIN 赋值给 最大和 和零到 当前总和其中,INT_MIN 表示最小整数值。
步骤2) 索引 0 处的值为 4。所以, 当前总和 = 0 + 4 = 4。因为 当前总和 大于 最大和, 最大和 变成 4。
步骤3) 索引 1 处的值为 -2。所以, 当前总和 = 4 + (-2) = 2。
这次 当前总和 小于 最大和因此,其价值 最大和 未更新。
步骤4) 下一个值是 1。将其加到 当前总和 给出3。因为 最大和 (4)仍然大于 当前总和, 最大和 未更新。
步骤5) 索引为 3 时,值为 3。递增 当前总和 乘以 3 得到 当前总和 = 6。
在这种情况下, 最大和 小于 当前总和,所以 最大和 已更新为以下值: 当前总和.
步骤6) 数组的最后一个元素是 -1。将其加到 当前总和 结果是 5,小于 最大和。 所以, 最大和 剩余6。
由于我们已经遍历到了数组的末尾,算法也到此结束。现在, 最大和 包含最大和,即 6。子数组为 {4, -2, 1, 3}。
昵称 Code 卡丹算法
function KadaneAlgorithm(): input: array maximum_sum, current_sum = 0 for each element in array: add the element with current_sum if current_sum is greater than the maximum_sum then maximum_sum = current_sum if current_sum is less than the element then current_sum = element return the value of maximum_sum
C++ Kadane 算法的实现
#include <iostream> using namespace std; void kadane(int array[], int n) { int current_sum = 0; int max_sum = -1e9; // -1e9 means -1,000,000,000 for (int i = 0; i < n; i++) { current_sum += array[i]; if (max_sum < current_sum) { max_sum = current_sum; } if (current_sum < array[i]) { current_sum = array[i]; } } cout << "largest sum is " << max_sum << endl; } int main() { int array[] = {-10, 5, 1, 6, -9, 2, -7, 3, -5}; kadane(array, sizeof(array) / sizeof(array[0])); }
输出:
largest sum is 12
Python Kadane 算法的实现
def kadane(numbers): current_sum = 0 max_sum = -1e9 for i in range(len(numbers)): current_sum += numbers[i] if max_sum < current_sum: max_sum = current_sum if current_sum < numbers[i]: current_sum = numbers[i] print("largest sum is ", max_sum) kadane([-10, 5, 1, 6, -9, 2, -7, 3, -5])
输出:
largest sum is 12
最大和连续子阵列的复杂度分析
这种简单的方法使用两个循环来计算每个可能的子数组和,并找到最大的和。这是一种暴力搜索方法;每个循环都会运行到数组末尾。 排列,给 O(N²) 时间。
Kadane 算法仅使用一个循环,时间复杂度为 O(N),空间复杂度为 O(1)。对于一个包含 100 个元素的数组,简单的算法需要执行 100 × 100 = 10,000 次运算,而 Kadane 算法仅需 100 次运算——对于大型输入,速度提升非常显著。










