Kadane算法 C++实现

算法通关之路:一文吃透Kadane算法(C++实现)

在算法面试和日常刷题中,最大子数组和(Maximum Subarray) 是一道经典必考题。暴力枚举所有子数组的解法时间复杂度高达 O(n²),而今天要讲的 Kadane算法(卡登算法) 能以 O(n) 时间复杂度 + O(1) 空间复杂度 完美解决这个问题,简洁又高效。

今天就用博客的形式,带你从原理到C++代码,彻底掌握Kadane算法!

一、问题背景

先明确问题:给定一个整数数组(包含正数、负数、0),找到一个连续的子数组,使其元素之和最大,返回这个最大和。

示例:

  • 输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
  • 输出:6(对应子数组 [4,-1,2,1]

暴力思路:遍历所有起点和终点,计算子数组和取最大值。但数组长度一大就会超时,这时候Kadane算法就派上用场了。

二、Kadane算法核心原理

Kadane算法的核心思想只有一句话:****每一步都做出当前最优选择,最终得到全局最优解(贪心思想)

我们遍历数组时,维护两个关键变量:

  1. 当前最大和(current_max) :以当前元素为结尾的连续子数组的最大和。
  2. 全局最大和(global_max):遍历过程中所有子数组的最大和(最终答案)。

核心决策逻辑:

对于数组中的每一个元素 nums[i],我们只有两种选择:

  1. nums[i] 加入前面的子数组current_max + nums[i]
  2. nums[i] 作为新子数组的起点nums[i]

我们取两者的最大值 作为新的 current_max,保证每一步都是当前最优。

同时,每次更新 current_max 后,用它更新 global_max,记录全局最优。

举个例子理解(数组 [-2,1,-3,4]):

  1. 初始:current_max=-2global_max=-2
  2. 元素1:max(1, -2+1)=1 → current_max=1global_max=1
  3. 元素-3:max(-3, 1+(-3))=-2 → current_max=-2global_max=1
  4. 元素4:max(4, -2+4)=4 → current_max=4global_max=4

三、算法步骤(清晰版)

  1. 初始化 current_maxglobal_max 为数组第一个元素
  2. 从数组第二个元素 开始遍历:
    • 更新 current_max = max(nums[i], current_max + nums[i])
    • 更新 global_max = max(global_max, current_max)
  3. 遍历结束,global_max 就是答案。

四、C++ 代码实现

1. 基础版(最简洁,面试首选)

直接实现核心逻辑,无多余操作,时间O(n),空间O(1):

cpp 复制代码
#include <iostream>
#include <vector>
#include <algorithm>  // 用于max函数
using namespace std;

// Kadane算法:求最大子数组和
int maxSubArray(vector<int>& nums) {
    // 边界判断:数组为空返回0(根据题目要求调整)
    if (nums.empty()) return 0;
    
    // 初始化当前最大和、全局最大和为第一个元素
    int current_max = nums[0];
    int global_max = nums[0];
    
    // 从第二个元素开始遍历
    for (int i = 1; i < nums.size(); ++i) {
        // 核心:当前最优选择
        current_max = max(nums[i], current_max + nums[i]);
        // 更新全局最优
        global_max = max(global_max, current_max);
    }
    
    return global_max;
}

// 测试代码
int main() {
    vector<int> nums = {-2, 1, -3, 4, -1, 2, 1, -5, 4};
    cout << "最大子数组和:" << maxSubArray(nums) << endl;  // 输出6
    return 0;
}

2. 进阶版:记录最大子数组的下标

如果题目不仅要求最大和,还要求输出子数组的起始、结束下标,可以在基础版上稍作修改:

cpp 复制代码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int maxSubArray(vector<int>& nums, int& start, int& end) {
    if (nums.empty()) return 0;
    
    int current_max = nums[0];
    int global_max = nums[0];
    int temp_start = 0;  // 临时记录当前子数组的起点
    
    for (int i = 1; i < nums.size(); ++i) {
        // 选择重新开始:更新临时起点
        if (nums[i] > current_max + nums[i]) {
            current_max = nums[i];
            temp_start = i;
        } else {
            // 选择加入前面的子数组
            current_max += nums[i];
        }
        
        // 更新全局最大和,记录最终起止下标
        if (current_max > global_max) {
            global_max = current_max;
            start = temp_start;
            end = i;
        }
    }
    
    return global_max;
}

// 测试代码
int main() {
    vector<int> nums = {-2, 1, -3, 4, -1, 2, 1, -5, 4};
    int start = 0, end = 0;
    int max_sum = maxSubArray(nums, start, end);
    
    cout << "最大子数组和:" << max_sum << endl;
    cout << "子数组下标:[" << start << ", " << end << "]" << endl;
    cout << "子数组:";
    for (int i = start; i <= end; ++i) {
        cout << nums[i] << " ";
    }
    return 0;
}

输出结果

复制代码
最大子数组和:6
子数组下标:[3, 6]
子数组:4 -1 2 1 

五、关键细节说明

  1. 全负数数组 :Kadane算法依然有效!比如数组 [-5,-3,-2,-1],算法会返回最大的单个元素 -1(符合题意,因为子数组至少包含一个元素)。
  2. 空间复杂度 :基础版只用到两个变量,是最优空间复杂度,无需额外开辟数组。
  3. 适用场景 :除了经典的最大子数组和,还能解决最大子矩阵和 (二维Kadane)、环形数组最大子数组和等变形题。

六、算法复杂度分析

  • 时间复杂度:O(n) ------ 只遍历数组一次,无嵌套循环。
  • 空间复杂度:O(1) ------ 仅使用常数个变量,不随数组长度变化。

这也是Kadane算法成为最优解的原因!

七、总结

Kadane算法是贪心思想 的经典应用,核心就是每一步只做最优选择

  • 要么延续前面的子数组,要么重新开始新子数组。
  • 时间O(n) + 空间O(1),是最大子数组和问题的最优解法。
  • C++实现简洁,面试手写无压力,还能轻松扩展记录子数组下标。

掌握这个算法,再也不怕最大子数组和相关的面试题啦!


核心要点回顾

  1. 核心思想:贪心,每一步取当前最优(延续/重启子数组)
  2. 关键变量current_max(当前结尾最大和)、global_max(全局最大和)
  3. 复杂度:O(n)时间,O(1)空间
  4. 适用场景:最大子数组和及各类变形题
相关推荐
handler012 小时前
【C++】二叉搜索树详解及其模拟实现(代码)
开发语言·c++·算法·c··二叉搜索树·搜索树
luj_17682 小时前
残熵算法的稳健防灾逻辑
c语言·开发语言·c++·经验分享·算法
玖釉-2 小时前
二叉树基础详解:TreeNode、buildTree、deleteTree 与 printTree 的实现原理(C++)
c++·windows·算法
Severus_black2 小时前
【初阶数据结构与算法】八大排序之非比较排序(计数排序),一次性讲清!
数据结构·算法·排序算法
better_liang2 小时前
每日Java面试场景题知识点之-如何设计分布式锁
java·redis·zookeeper·面试·分布式锁
战族狼魂2 小时前
集 “自动飞行、智能识别、实时预警、勤务联动” 于一体的高速公路应急车道无人机检测系统方案
java·人工智能·大模型·无人机
罗西的思考2 小时前
【Agentic RL / 强化学习 / OPD】OpenClaw-RL 源码阅读笔记 --- (4)--- 系统架构
人工智能·算法·机器学习
QiLinkOS2 小时前
从技术到资产的跃迁:企业专利布局的深层逻辑
c语言·数据结构·c++·单片机·嵌入式硬件·算法·开源
一只鹿鹿鹿2 小时前
信息化项目管理规范(参考Word文件)
java·大数据·运维·开发语言·数据库