从零开始写算法——普通数组类题:最大子数组和 & 合并区间(C++)

在刷算法时,有两类题非常高频:连续子数组相关问题区间处理问题。本文将通过两道典型题目来理解它们的本质思路与代码实现。


一、最大子数组和(Maximum Subarray)

题目

给你一个整数数组 nums,请找出一个具有最大和的连续子数组(至少包含一个元素),返回其最大和。


思路解析

采用 前缀和 + 最小前缀和 的思想(将它转化为买卖股票机问题):

当前前缀和 - 历史最小前缀和 = 当前能得到的最大连续子数组和

  • pre_sum 表示当前的前缀和

  • pre_sum_min 记录遇到的最小前缀和

  • 每次更新结果 ans = max(ans, pre_sum - pre_sum_min)

  • 不断更新 pre_sum_min

这就像"低买高卖股票问题":

前面最低的时候买入,现在卖出,赚得最多


✔代码实现

cpp 复制代码
class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        // 思路: 利用前缀和 将其转化为一个买卖股票机的问题
        int ans = INT_MIN;
        int pre_sum_min = 0;
        int pre_sum = 0;
        for (int x : nums) {
            pre_sum += x;
            ans = max(ans, pre_sum - pre_sum_min);
            pre_sum_min = min(pre_sum, pre_sum_min);
        }
        return ans;
    }
};

复杂度分析

项目 数值
时间复杂度 O(n)
空间复杂度 O(1)
思想核心 前缀和 & 动态更新最优

二、合并区间(Merge Intervals)

题目

给定一组区间,将重叠区间合并为一个。


思路解析

基本策略:

  1. 先按区间起点排序

  2. 维护当前合并区间 [start, end]

  3. 遍历过程中判断是否重叠

    • 如果重叠:更新 end = max(end, 当前区间的end)

    • 如果不重叠:将已有区间压入结果,新建区间

注意:最后一个区间需要手动加入答案。


✔代码实现

cpp 复制代码
class Solution {
public:
    vector<vector<int>> merge(vector<vector<int>>& intervals) {
        // 思路: 先排序,然后通过start 和 end 比较更新区间,加入答案,别忘了最后单独加入,因为最后构成不了不符合if的条件
        vector<vector<int>> ans;
        sort(intervals.begin(), intervals.end());
        int start = intervals[0][0];
        int end = intervals[0][1];
        for (int i = 1; i < intervals.size(); ++i) {
            if (intervals[i][0] > end) {
                ans.push_back({start, end});
                start = intervals[i][0];
                end = intervals[i][1];
            }
            else {
                end = max(end,intervals[i][1]);
            }
        }
        ans.push_back({start, end});
        return ans;
    }
};

复杂度分析

项目 数值
排序开销 O(n log n)
遍历开销 O(n)
总复杂度 O(n log n)
技巧核心 排序 + 贪心合并

总结 & 对比

题目 核心策略 是否排序 是否贪心 难点
最大子数组和 前缀和 & 动态更新最低点 把连续子数组转成差值最大问题
合并区间 排序 + 贪心扩展区间 细节处理 & 最后区间别漏

小结

最大子数组和 ------ "找最低点买入,当前卖出"

合并区间 ------ "先排好队,再合并重叠的人"

相关推荐
醒过来摸鱼16 小时前
递归三种分类方法
算法
炽烈小老头16 小时前
【每天学习一点算法 2025/12/22】将有序数组转换为二叉搜索树
学习·算法
呱呱巨基17 小时前
Linux 进程控制
linux·c++·笔记·学习
jghhh0117 小时前
POCS(凸集投影)算法解决部分k空间数据缺失导致吉布斯伪影
算法
罗湖老棍子17 小时前
最小函数值(minval)(信息学奥赛一本通- P1370)
数据结构·c++·算法··优先队列·
LYFlied17 小时前
【每日算法】LeetCode 4. 寻找两个正序数组的中位数
算法·leetcode·面试·职场和发展
长安er17 小时前
LeetCode 62/64/5/1143多维动态规划核心题型总结
算法·leetcode·mybatis·动态规划
鹿角片ljp17 小时前
力扣 83: 删除排序链表中的重复元素(Java实现)
java·leetcode·链表
LYFlied17 小时前
【每日算法】LeetCode 208. 实现 Trie (前缀树)
数据结构·算法·leetcode·面试·职场和发展
肆悟先生17 小时前
3.17 内联函数
c++