【贪心算法】(经典实战应用解析(二):最⻓递增⼦序列、递增的三元⼦序列、最⻓连续递增序列、买卖股票的最佳时机、买卖股票的最佳时机II)


🔥承渊政道: 个人主页
❄️个人专栏: 《C语言基础语法知识》 《数据结构与算法》 《C++知识内容》 《Linux系统知识》 《算法刷题指南》 《测评文章活动推广》 《大模型语言路线学习》
✨逆境不吐心中苦,顺境不忘来时路!✨ 🎬 博主简介:

在贪心算法的学习过程中,数组类问题是非常重要的一类应用场景.很多题目表面上看只是简单的遍历、比较和更新,但真正的核心在于:如何在每一步选择中保留对后续最有利的状态 .这也正是贪心算法区别于普通模拟的关键所在.在上一篇内容中,我们已经通过一些经典题目初步了解了贪心算法在找零、排序、优先队列和趋势判断中的应用.本文将继续围绕贪心算法展开,重点分析一组与 递增序列股票买卖 相关的经典实战题目,包括:最长递增子序列、递增的三元子序列、最长连续递增序列、买卖股票的最佳时机、买卖股票的最佳时机 II.这些题目虽然都可以从数组遍历入手,但背后的贪心策略并不完全相同.例如,在递增序列问题中,我们往往需要维护一个更小、更有潜力的结尾值,为后续元素创造更多连接机会;在连续递增序列问题中,则需要抓住相邻元素之间的变化趋势;而在股票买卖问题中,贪心思想体现为寻找最低买入点、捕捉上涨区间,或者将每一段可获得的利润及时累加.通过本文的讲解,我们不仅会分析每道题的解题思路和代码实现,还会重点理解其中的贪心选择依据:为什么当前这样更新是最优的?为什么不会影响后续结果?局部最优又是如何逐步转化为最终答案的?希望通过这几道经典题目的实战解析,能够帮助大家进一步掌握贪心算法在数组问题中的常见套路,建立起从题意分析到贪心策略设计的完整思维过程,为后续解决更多复杂的最优解问题打下基础.废话不多说,下面跟着小编的节奏🎵一起去疯狂的学习吧!

目录

1.最长递增子序列(OJ题)


解法(贪心):

贪心策略:我们在考虑最长递增子序列的长度的时候,其实并不关心这个序列长什么样子,我们只是关心最后一个元素是谁.这样新来一个元素之后,我们就可以判断是否可以拼接到它的后面.因此,我们可以创建一个数组,统计长度为 x 的递增子序列中,最后一个元素是谁.为了尽可能的让这个序列更长,我们仅需统计长度为 x 的所有递增序列中最后一个元素的最小值.统计的过程中发现,数组中的数呈现递增趋势,因此可以使用二分来查找插入位置.




核心代码

cpp 复制代码
class Solution
{
public:
    //函数功能:返回数组nums的最长严格递增子序列的长度
    int lengthOfLIS(vector<int>& nums)
    {
        //获取数组的总长度
        int n = nums.size();
        //核心数组ret:
        //存储【长度为 i 的最长递增子序列的最小末尾元素】
        //贪心思想:末尾越小,后续越容易接更长的子序列
        vector<int> ret;
        //初始化:将数组第一个元素放入结果数组
        ret.push_back(nums[0]);

        //从第二个元素开始遍历整个数组
        for(int i = 1; i < n; i++)
        {
            //情况1:当前数字 > ret的最后一个元素
            //说明可以直接接在最长子序列后面,长度+1
            if(nums[i] > ret.back()) 
            {
                ret.push_back(nums[i]);
            }
            //情况2:当前数字 <= ret的最后一个元素
            //用二分查找找到ret中第一个 >= 当前数的位置,替换它
            else
            {
                //二分查找的左右边界
                int left = 0, right = ret.size() - 1;
                //二分查找:找到第一个大于等于nums[i]的元素下标
                while(left < right)
                {
                    //等价于 mid = (left + right) / 2,右移运算效率更高
                    int mid = (left + right) >> 1;
                    //中间值 < 当前数,说明目标在右半区间
                    if(ret[mid] < nums[i]) 
                        left = mid + 1;
                    //中间值 >= 当前数,目标在左半区间
                    else 
                        right = mid;
                }
                //替换该位置元素,维持ret数组的单调性,优化后续子序列
                ret[left] = nums[i]; 
            }
        }
        //ret数组的长度 就是 最长递增子序列的长度
        return ret.size();
    }
};

完整测试代码

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

class Solution
{
public:
    // 函数功能:返回数组 nums 的最长严格递增子序列的长度
    int lengthOfLIS(vector<int>& nums)
    {
        // 获取数组的总长度
        int n = nums.size();

        // 边界情况:空数组没有递增子序列
        if (n == 0)
            return 0;

        // 核心数组 ret:
        // 存储【长度为 i 的最长递增子序列的最小末尾元素】
        // 贪心思想:末尾越小,后续越容易接更长的子序列
        vector<int> ret;

        // 初始化:将数组第一个元素放入结果数组
        ret.push_back(nums[0]);

        // 从第二个元素开始遍历整个数组
        for (int i = 1; i < n; i++)
        {
            // 情况1:当前数字 > ret 的最后一个元素
            // 说明可以直接接在最长子序列后面,长度 +1
            if (nums[i] > ret.back())
            {
                ret.push_back(nums[i]);
            }
                // 情况2:当前数字 <= ret 的最后一个元素
                // 用二分查找找到 ret 中第一个 >= 当前数的位置,替换它
            else
            {
                int left = 0, right = ret.size() - 1;

                // 二分查找:找到第一个大于等于 nums[i] 的元素下标
                while (left < right)
                {
                    int mid = (left + right) >> 1;

                    if (ret[mid] < nums[i])
                        left = mid + 1;
                    else
                        right = mid;
                }

                // 替换该位置元素,维持 ret 数组的单调性
                ret[left] = nums[i];
            }
        }

        // ret 数组的长度就是最长递增子序列的长度
        return ret.size();
    }
};

void printVector(const vector<int>& nums)
{
    cout << "[";

    for (size_t i = 0; i < nums.size(); i++)
    {
        cout << nums[i];

        if (i != nums.size() - 1)
            cout << ", ";
    }

    cout << "]";
}

int main()
{
    Solution sol;

    vector<vector<int>> testCases = {
            {10, 9, 2, 5, 3, 7, 101, 18},  // 普通情况,结果为 4
            {0, 1, 0, 3, 2, 3},            // 包含重复和回落,结果为 4
            {7, 7, 7, 7, 7, 7, 7},         // 全部相等,结果为 1
            {1, 2, 3, 4, 5, 6},            // 严格递增,结果为 6
            {6, 5, 4, 3, 2, 1},            // 严格递减,结果为 1
            {1},                           // 单个元素,结果为 1
            {},                            // 空数组,结果为 0
            {4, 10, 4, 3, 8, 9},           // 常见测试,结果为 3
            {2, 5, 1, 8, 3, 9, 4},         // 多次替换 ret 元素,结果为 4
            {-1, 3, 4, -2, 0, 6, 2, 3}     // 包含负数,结果为 4
    };

    for (int i = 0; i < testCases.size(); i++)
    {
        vector<int> nums = testCases[i];

        cout << "测试用例 " << i + 1 << ":";
        printVector(nums);
        cout << endl;

        cout << "最长递增子序列长度:";
        cout << sol.lengthOfLIS(nums) << endl;

        cout << "------------------------" << endl;
    }

    return 0;
}

2.递增的三元子序列(OJ题)


解法(贪心):

贪心策略:最长递增子序列的简化版.不用一个数组存数据,仅需两个变量即可.也不用二分插入位置,仅需两次比较就可以找到插入位置.




核心代码

cpp 复制代码
class Solution
{
public:
    //函数功能:返回数组是否存在递增三元子序列
    bool increasingTriplet(vector<int>& nums)
    {
        //边界:数组长度小于3直接返回false
        if(nums.size() < 3) return false;
        
        //a:记录遍历过程中【最小的第一个数】
        //b:记录遍历过程中【第二小的第二个数】
        //初始化:a为数组第一个元素,b为整型最大值(初始无第二大数)
        int a = nums[0], b = INT_MAX;

        //从数组第二个元素开始遍历
        for(int i = 1; i < nums.size(); i++)
        {
            //情况1:当前数字 > b → 找到满足条件的三元组 a < b < nums[i],直接返回true
            if(nums[i] > b) 
                return true;
            //情况2:当前数字 > a 且 ≤ b → 更新b为更小的值,更易找到第三个数
            else if(nums[i] > a) 
                b = nums[i];
            //情况3:当前数字 ≤ a → 更新a为更小的值,优化后续匹配
            else 
                a = nums[i];
        }

        //遍历结束未找到,返回false
        return false;
    }
};

完整测试代码

cpp 复制代码
#include <iostream>
#include <vector>
#include <climits>

using namespace std;

class Solution
{
public:
    // 函数功能:返回数组是否存在递增三元子序列
    bool increasingTriplet(vector<int>& nums)
    {
        // 边界:数组长度小于 3 直接返回 false
        if (nums.size() < 3)
            return false;

        // a:记录遍历过程中【最小的第一个数】
        // b:记录遍历过程中【第二小的第二个数】
        int a = nums[0], b = INT_MAX;

        // 从数组第二个元素开始遍历
        for (int i = 1; i < nums.size(); i++)
        {
            // 情况1:当前数字 > b
            // 找到满足条件的三元组 a < b < nums[i]
            if (nums[i] > b)
                return true;

                // 情况2:当前数字 > a 且 <= b
                // 更新 b 为更小的值,更容易找到第三个数
            else if (nums[i] > a)
                b = nums[i];

                // 情况3:当前数字 <= a
                // 更新 a 为更小的值,优化后续匹配
            else
                a = nums[i];
        }

        // 遍历结束未找到,返回 false
        return false;
    }
};

void printVector(const vector<int>& nums)
{
    cout << "[";

    for (size_t i = 0; i < nums.size(); i++)
    {
        cout << nums[i];

        if (i != nums.size() - 1)
            cout << ", ";
    }

    cout << "]";
}

void printBool(bool result)
{
    cout << (result ? "true" : "false");
}

int main()
{
    Solution sol;

    vector<vector<int>> testCases = {
            {1, 2, 3, 4, 5},          // 存在递增三元子序列:1,2,3
            {5, 4, 3, 2, 1},          // 不存在
            {2, 1, 5, 0, 4, 6},       // 存在:0,4,6
            {1, 1, 1, 1},             // 全部相等,不存在
            {1, 2},                   // 长度小于 3,不存在
            {},                       // 空数组,不存在
            {2, 4, -2, -3},           // 不存在
            {20, 100, 10, 12, 5, 13}, // 存在:10,12,13
            {1, 5, 0, 4, 1, 3},       // 存在:0,1,3
            {5, 1, 5, 5, 2, 5, 4},    // 存在:1,2,5
            {2, 1, 5, 0, 3},          // 不存在
            {-1, 0, 1},               // 存在:-1,0,1
            {1, 2, 2, 2, 3}           // 存在:1,2,3
    };

    for (int i = 0; i < testCases.size(); i++)
    {
        vector<int> nums = testCases[i];

        cout << "测试用例 " << i + 1 << ":";
        printVector(nums);
        cout << endl;

        cout << "是否存在递增三元子序列:";
        printBool(sol.increasingTriplet(nums));
        cout << endl;

        cout << "------------------------" << endl;
    }

    return 0;
}

3.最长连续递增序列(OJ题)


解法(贪心):

贪心策略:找到以某个位置为起点的最长连续递增序列之后(设这个序列的末尾为 j 位置),接下来直接以 j + 1 的位置为起点寻找下一个最长连续递增序列.




核心代码

cpp 复制代码
class Solution
{
public:
    //函数功能:返回最长连续递增子序列的长度
    int findLengthOfLCIS(vector<int>& nums)
    {
        //ret:记录最终的最长连续递增子序列长度
        //n:数组的总长度
        int ret = 0, n = nums.size();
        
        //i 作为连续递增区间的起始位置,不写i++,手动更新起始位置
        for(int i = 0; i < n; )
        {
            //j 从i的下一位开始,寻找当前递增区间的结束位置
            int j = i + 1;
            
            //循环判断:如果j不越界,且后一个数 > 前一个数,说明连续递增,j继续后移
            while(j < n && nums[j] > nums[j - 1]) 
                j++;
            
            //计算当前连续递增区间的长度(j-i),更新最大值
            ret = max(ret, j - i);
            
            //关键:将下一个区间的起始位置i 直接跳到 j,跳过已遍历的区间,优化效率
            i = j; 
        }
        //返回最终的最长长度
        return ret;
    }
};

完整测试代码

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

class Solution
{
public:
    // 函数功能:返回最长连续递增子序列的长度
    int findLengthOfLCIS(vector<int>& nums)
    {
        // ret:记录最终的最长连续递增子序列长度
        // n:数组的总长度
        int ret = 0, n = nums.size();

        // i 作为连续递增区间的起始位置,不写 i++,手动更新起始位置
        for (int i = 0; i < n; )
        {
            // j 从 i 的下一位开始,寻找当前递增区间的结束位置
            int j = i + 1;

            // 如果 j 不越界,且后一个数 > 前一个数,说明连续递增
            while (j < n && nums[j] > nums[j - 1])
                j++;

            // 计算当前连续递增区间的长度
            ret = max(ret, j - i);

            // 将下一个区间的起始位置 i 直接跳到 j
            i = j;
        }

        return ret;
    }
};

void printVector(const vector<int>& nums)
{
    cout << "[";

    for (size_t i = 0; i < nums.size(); i++)
    {
        cout << nums[i];

        if (i != nums.size() - 1)
            cout << ", ";
    }

    cout << "]";
}

int main()
{
    Solution sol;

    vector<vector<int>> testCases = {
            {1, 3, 5, 4, 7},              // 最长连续递增:[1,3,5],长度 3
            {2, 2, 2, 2, 2},              // 全部相等,长度 1
            {1, 2, 3, 4, 5},              // 整体递增,长度 5
            {5, 4, 3, 2, 1},              // 整体递减,长度 1
            {1},                          // 单个元素,长度 1
            {},                           // 空数组,长度 0
            {1, 3, 5, 7},                 // 全部连续递增,长度 4
            {7, 1, 2, 3, 0, 4, 5, 6},     // 多段递增,最长长度 4
            {1, 2, 2, 3, 4, 1, 2, 3, 4},  // 包含重复元素,最长长度 4
            {-3, -2, -1, 0, -1, 1, 2},    // 包含负数,最长长度 4
            {10, 20, 30, 5, 10, 15, 20},  // 后半段更长,最长长度 4
            {3, 4, 5, 1, 2, 3, 4, 0}      // 中间一段最长,长度 4
    };

    for (int i = 0; i < testCases.size(); i++)
    {
        vector<int> nums = testCases[i];

        cout << "测试用例 " << i + 1 << ":";
        printVector(nums);
        cout << endl;

        cout << "最长连续递增子序列长度:";
        cout << sol.findLengthOfLCIS(nums) << endl;

        cout << "------------------------" << endl;
    }

    return 0;
}

4.买卖股票的最佳时机(OJ题)


解法(贪心):

贪心策略:由于只能交易一次,所以对于某一个位置 i,要想获得最大利润,仅需知道前面所有元素的最小值.然后在最小值的位置买入股票,在当前位置卖出股票即可.




核心代码

cpp 复制代码
class Solution
{
public:
    //函数功能:传入股票价格数组,返回最大利润(无利润则返回0)
    int maxProfit(vector<int>& prices)
    {
        //ret:存储最终的最大利润,初始化为0(不交易时利润为0)
        int ret = 0; 

        //遍历数组:
        //i:遍历下标
        //prevMin:记录【遍历到当前位置之前】的最低股票价格,初始化为整型最大值
        for(int i = 0, prevMin = INT_MAX; i < prices.size(); i++)
        {
            //核心步骤1:计算【当天价格 - 之前的最低价】,更新最大利润
            //必须先算利润,再更新最小值!保证用的是「之前」的最低价
            ret = max(ret, prices[i] - prevMin); 
            
            //核心步骤2:更新「遍历过的价格中的最小值」,为下一天计算利润做准备
            prevMin = min(prevMin, prices[i]); 
        }

        //返回最大利润
        return ret;
    }
};

完整测试代码

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

class Solution
{
public:
    // 函数功能:传入股票价格数组,返回最大利润(无利润则返回 0)
    int maxProfit(vector<int>& prices)
    {
        // 边界情况:没有股票价格,无法交易
        if (prices.empty())
            return 0;

        // ret:存储最终的最大利润,初始化为 0(不交易时利润为 0)
        int ret = 0;

        // prevMin:记录遍历到当前位置之前的最低股票价格
        int prevMin = prices[0];

        // 从第二天开始遍历
        for (int i = 1; i < prices.size(); i++)
        {
            // 核心步骤1:计算当天卖出可以获得的利润
            ret = max(ret, prices[i] - prevMin);

            // 核心步骤2:更新历史最低买入价格
            prevMin = min(prevMin, prices[i]);
        }

        // 返回最大利润
        return ret;
    }
};

void printVector(const vector<int>& nums)
{
    cout << "[";

    for (size_t i = 0; i < nums.size(); i++)
    {
        cout << nums[i];

        if (i != nums.size() - 1)
            cout << ", ";
    }

    cout << "]";
}

int main()
{
    Solution sol;

    vector<vector<int>> testCases = {
            {7, 1, 5, 3, 6, 4},       // 最低 1 买入,最高 6 卖出,利润 5
            {7, 6, 4, 3, 1},          // 一直下跌,利润 0
            {1, 2, 3, 4, 5},          // 一直上涨,利润 4
            {2, 4, 1},                // 2 买入,4 卖出,利润 2
            {3, 3, 3, 3},             // 价格不变,利润 0
            {1},                      // 只有一天,无法交易,利润 0
            {},                       // 空数组,利润 0
            {5, 1, 2, 10, 3, 12},     // 1 买入,12 卖出,利润 11
            {10, 7, 5, 8, 11, 9},     // 5 买入,11 卖出,利润 6
            {2, 1, 2, 0, 1}           // 1 买入,2 卖出,利润 1
    };

    for (int i = 0; i < testCases.size(); i++)
    {
        vector<int> prices = testCases[i];

        cout << "测试用例 " << i + 1 << ":";
        printVector(prices);
        cout << endl;

        cout << "最大利润:";
        cout << sol.maxProfit(prices) << endl;

        cout << "------------------------" << endl;
    }

    return 0;
}

5.买卖股票的最佳时机II(OJ题)


解法(贪心):

贪心策略:由于可以进行无限次交易,所以只要是一个上升区域,我们就把利润拿到手就好了.




核心代码

cpp 复制代码
//解法一:双指针法 - 找到完整的上涨区间,一次性计算利润
class Solution
{
public:
    //函数功能:传入股票价格数组,返回最大利润
    int maxProfit(vector<int>& p)
    {
        //ret:累计总利润
        //n:数组长度
        int ret = 0, n = p.size();
        
        //遍历数组,i 标记【买入点】
        for(int i = 0; i < n; i++)
        {
            //j 从 i 出发,寻找当前上涨区间的【卖出点】
            int j = i;
            //循环:只要后一天价格更高,就继续持有,j 后移
            while(j + 1 < n && p[j + 1] > p[j]) 
                j++;
            
            //计算当前完整上涨区间的利润,累加到总利润
            ret += p[j] - p[i];
            //关键:i 直接跳转到 j,跳过已遍历的上涨区间,开始寻找下一个上涨段
            i = j;
        }
        //返回总利润
        return ret;
    }
};

完整测试代码

cpp 复制代码
#include <iostream>
#include <vector>

using namespace std;

// 解法一:双指针法 - 找到完整的上涨区间,一次性计算利润
class Solution
{
public:
    // 函数功能:传入股票价格数组,返回最大利润
    int maxProfit(vector<int>& p)
    {
        // ret:累计总利润
        // n:数组长度
        int ret = 0, n = p.size();

        // 遍历数组,i 标记【买入点】
        for (int i = 0; i < n; i++)
        {
            // j 从 i 出发,寻找当前上涨区间的【卖出点】
            int j = i;

            // 只要后一天价格更高,就继续持有,j 后移
            while (j + 1 < n && p[j + 1] > p[j])
                j++;

            // 计算当前完整上涨区间的利润,累加到总利润
            ret += p[j] - p[i];

            // i 直接跳转到 j,跳过已遍历的上涨区间
            i = j;
        }

        // 返回总利润
        return ret;
    }
};

void printVector(const vector<int>& nums)
{
    cout << "[";

    for (size_t i = 0; i < nums.size(); i++)
    {
        cout << nums[i];

        if (i != nums.size() - 1)
            cout << ", ";
    }

    cout << "]";
}

int main()
{
    Solution sol;

    vector<vector<int>> testCases = {
            {7, 1, 5, 3, 6, 4},       // 两段上涨:1->5,3->6,总利润 7
            {1, 2, 3, 4, 5},          // 一直上涨:1->5,利润 4
            {7, 6, 4, 3, 1},          // 一直下跌:利润 0
            {3, 3, 3, 3},             // 价格不变:利润 0
            {1},                      // 只有一天:利润 0
            {},                       // 空数组:利润 0
            {2, 1, 2, 0, 1},          // 两段上涨:1->2,0->1,总利润 2
            {6, 1, 3, 2, 4, 7},       // 两段上涨:1->3,2->7,总利润 7
            {1, 3, 2, 8, 4, 9},       // 三段上涨:1->3,2->8,4->9,总利润 13
            {5, 4, 5, 6, 1, 2, 3},    // 两段上涨:4->6,1->3,总利润 4
            {10, 20, 15, 25, 5, 30},  // 三段上涨:10->20,15->25,5->30,总利润 45
            {1, 2, 2, 3, 4}           // 平台后继续上涨:1->2,2->4,总利润 3
    };

    for (int i = 0; i < testCases.size(); i++)
    {
        vector<int> prices = testCases[i];

        cout << "测试用例 " << i + 1 << ":";
        printVector(prices);
        cout << endl;

        cout << "最大利润:";
        cout << sol.maxProfit(prices) << endl;

        cout << "------------------------" << endl;
    }

    return 0;
}






核心代码

cpp 复制代码
//解法二:逐日拆分法 - 极简贪心,只赚每一天的上涨差价
class Solution
{
public:
    int maxProfit(vector<int>& prices)
    {
        //总利润初始化为0
        int ret = 0;
        
        //从第二天开始遍历(对比前一天价格)
        for(int i = 1; i < prices.size(); i++)
        {
            //核心贪心:只要今天价格 > 昨天价格,就赚取这一天的差价
            if(prices[i] > prices[i - 1])
                ret += prices[i] - prices[i - 1];
        }
        //所有小利润之和 = 最大总利润
        return ret;
    }
};

完整测试代码

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

// 解法二:逐日拆分法 - 极简贪心,只赚每一天的上涨差价
class Solution
{
public:
    int maxProfit(vector<int>& prices)
    {
        // 总利润初始化为 0
        int ret = 0;

        // 从第二天开始遍历,对比前一天价格
        for (int i = 1; i < prices.size(); i++)
        {
            // 核心贪心:只要今天价格 > 昨天价格,就赚取这一天的差价
            if (prices[i] > prices[i - 1])
                ret += prices[i] - prices[i - 1];
        }

        // 所有小利润之和 = 最大总利润
        return ret;
    }
};

void printVector(const vector<int>& nums)
{
    cout << "[";

    for (size_t i = 0; i < nums.size(); i++)
    {
        cout << nums[i];

        if (i != nums.size() - 1)
            cout << ", ";
    }

    cout << "]";
}

int main()
{
    Solution sol;

    vector<vector<int>> testCases = {
            {7, 1, 5, 3, 6, 4},       // 上涨差价:(5-1) + (6-3) = 7
            {1, 2, 3, 4, 5},          // 每天都上涨,总利润 4
            {7, 6, 4, 3, 1},          // 一直下跌,总利润 0
            {3, 3, 3, 3},             // 价格不变,总利润 0
            {1},                      // 只有一天,无法交易,利润 0
            {},                       // 空数组,利润 0
            {2, 1, 2, 0, 1},          // (2-1) + (1-0) = 2
            {6, 1, 3, 2, 4, 7},       // (3-1) + (4-2) + (7-4) = 7
            {1, 3, 2, 8, 4, 9},       // (3-1) + (8-2) + (9-4) = 13
            {5, 4, 5, 6, 1, 2, 3},    // (5-4) + (6-5) + (2-1) + (3-2) = 4
            {10, 20, 15, 25, 5, 30},  // (20-10) + (25-15) + (30-5) = 45
            {1, 2, 2, 3, 4}           // (2-1) + (3-2) + (4-3) = 3
    };

    for (int i = 0; i < testCases.size(); i++)
    {
        vector<int> prices = testCases[i];

        cout << "测试用例 " << i + 1 << ":";
        printVector(prices);
        cout << endl;

        cout << "最大利润:";
        cout << sol.maxProfit(prices) << endl;

        cout << "------------------------" << endl;
    }

    return 0;
}

🚀真正的勇者不是流泪的人,而是含泪奔跑的人!


敬请期待下一篇文章内容的更新【贪心算法】(经典实战应用解析(三):K次取反后最⼤化的数组和、按⾝⾼排序、优势洗牌、最⻓回⽂串、增减字符串匹配)


每日心灵鸡汤: 人生缓缓,自有答案!

允许事情悬而未决,拥抱生活的"不确定性",允许事情停在"逗号"那里,接受那些不确定、没做完.做你能做的,其余的,先不去想.你以为的停滞,也许是生活正在为你画一条更好的路.事情悬着,不是失控,它是让你在"没答案"的这段时间里,练习信任、练习稳住自己,将内心调整到"能接住" 的状态.不必刻意等待,能解决的事,不用急,解决不了的事,急也没用.与其提前焦虑明天,不如好好把握今天事情有它的节奏,而你也有自己的节奏,你不必用力攥住一切,手摊开,才能拥有更多,人生缓缓,答案在路上.

相关推荐
li星野1 小时前
动态规划十题通关:从爬楼梯到编辑距离(Python + C++)
c++·python·学习·算法·动态规划
披着假发的程序唐1 小时前
STM32 H743 MPU的配置使用方法
linux·c语言·c++·驱动开发·stm32·单片机·mcu
栈溢出了1 小时前
GAT(Graph Attention Network)学习笔记
人工智能·深度学习·算法·机器学习
Tutankaaa1 小时前
学校知识竞赛怎么组织?从班级到年级的进阶方案
经验分享·学习·算法·职场和发展
qcx231 小时前
混合检索+重排序:当前 RAG 精度提升最成熟的工程路径
算法·ai·llm·agent·rag·agentic
小此方1 小时前
Re:Linux系统篇(十二)工具篇 · 四:make与Makefile:高效管理 C++ 工程项目构建
linux·运维·c++·开发工具
洛水水1 小时前
【力扣100题】42.杨辉三角
算法·leetcode·职场和发展
東隅已逝,桑榆非晚1 小时前
深⼊理解指针(3)
c语言·数据结构·笔记·算法·排序算法
云小逸1 小时前
【Codex 使用教程:从项目规则、Skills、Rules 到 Hooks】
c++·人工智能·ai·codex