LeetCode-17day:贪心算法

贪心算法经典题目总结(C++实现)

贪心算法是一种在每一步选择中都采取当前状态下最优(即最有利)的选择,从而希望导致结果是全局最优的算法。本文总结了四道经典的贪心算法问题,帮助你更好地理解和掌握贪心算法的应用。


🟢 1. 买卖股票的最佳时机(Best Time to Buy and Sell Stock)

📄 题目描述:

给定一个数组 prices,其中第 i 个元素是第 i 天的股票价格。假设你最多只能进行一次交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。

🧠 解题思路(简洁版)

  • 一次遍历
    • 遍历价格数组,维护当前最低价格 minp 和最大利润 maxp
    • 每天更新最低价格和最大利润。

⏱️ 复杂度分析

  • 时间复杂度:O(n),其中 n 为价格数组长度。
  • 空间复杂度:O(1)

✅ C++ 实现

cpp 复制代码
class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int minp = 1e9, maxp = 0;
        for (auto& price : prices) {
            maxp = max(maxp, price - minp);
            minp = min(minp, price);
        }
        return maxp;
    }
};

🟢 2. 跳跃游戏(Jump Game)

📄 题目描述:

给定一个非负整数数组 nums,你最初位于数组的第一个位置。数组中的每个元素代表你在该位置可以跳跃的最大长度。判断你是否能够到达最后一个位置。

🧠 解题思路(简洁版)

  • 贪心算法
    • 遍历数组,维护当前能到达的最远位置 rightmost
    • 若当前位置可达,则更新最远位置。
    • 若最远位置覆盖数组末尾,返回 true

⏱️ 复杂度分析

  • 时间复杂度:O(n),其中 n 为数组长度。
  • 空间复杂度:O(1)

✅ C++ 实现

cpp 复制代码
class Solution {
public:
    bool canJump(vector<int>& nums) {
        int n = nums.size();
        int rightmost = 0;
        for (int i = 0; i < n; i++) {
            if (i <= rightmost) {
                rightmost = max(rightmost, i + nums[i]);
                if (rightmost >= n - 1) return true;
            }
        }
        return false;
    }
};

🟢 3. 跳跃游戏 II(Jump Game II)

📄 题目描述:

给定一个非负整数数组 nums,你最初位于数组的第一个位置。数组中的每个元素代表你在该位置可以跳跃的最大长度。你的目标是使用最少的跳跃次数到达数组的最后一个位置。

🧠 解题思路(简洁版)

  • 贪心算法
    • 遍历数组,维护当前能到达的最远位置 maxpos 和当前步的边界 end
    • 若当前位置到达边界,则更新边界为最远位置并增加步数。
    • 直到覆盖数组末尾。

⏱️ 复杂度分析

  • 时间复杂度:O(n),其中 n 为数组长度。
  • 空间复杂度:O(1)

✅ C++ 实现

cpp 复制代码
class Solution {
public:
    int jump(vector<int>& nums) {
        int maxpos = 0, n = nums.size(), end = 0, step = 0;
        for (int i = 0; i < n - 1; i++) {
            if (maxpos >= i) {
                maxpos = max(maxpos, i + nums[i]);
                if (i == end) {
                    end = maxpos;
                    step++;
                }
            }
        }
        return step;
    }
};

🟢 4. 划分字母区间(Partition Labels)

📄 题目描述:

给定一个字符串 s,将字符串划分成若干个字母区间,每个区间内的字母互不相同。返回每个区间的长度。

🧠 解题思路(简洁版)

  • 贪心算法
    • 预处理每个字符的最后出现位置。
    • 遍历字符串,维护当前区间的起始和结束位置。
    • 当遍历到当前区间的结束位置时,记录区间长度并更新起始位置。

⏱️ 复杂度分析

  • 时间复杂度:O(n),其中 n 为字符串长度。
  • 空间复杂度:O(1),固定大小的数组。

✅ C++ 实现

cpp 复制代码
class Solution {
public:
    vector<int> partitionLabels(string s) {
        int last[26];
        int length = s.size();
        for (int i = 0; i < length; i++) {
            last[s[i] - 'a'] = i;
        }

        vector<int> partition;
        int start = 0, end = 0;
        for (int i = 0; i < length; i++) {
            end = max(end, last[s[i] - 'a']);
            if (i == end) {
                partition.push_back(end - start + 1);
                start = end + 1;
            }
        }
        return partition;
    }
};

📌 总结

题目 方法 时间复杂度 空间复杂度
买卖股票的最佳时机 一次遍历 O(n) O(1)
跳跃游戏 贪心算法 O(n) O(1)
跳跃游戏 II 贪心算法 O(n) O(1)
划分字母区间 贪心算法 O(n) O(1)

希望本文对你有所帮助!如果你还有其他问题,欢迎继续提问。

相关推荐
wanzhong23337 分钟前
CUDA学习5-矩阵乘法(共享内存版)
深度学习·学习·算法·cuda·高性能计算
fufu031132 分钟前
Linux环境下的C语言编程(四十八)
数据结构·算法·排序算法
Yingye Zhu(HPXXZYY)1 小时前
Solution to Luogu P6340
算法
小熳芋1 小时前
单词搜索- python-dfs&剪枝
算法·深度优先·剪枝
Xの哲學1 小时前
Linux SLAB分配器深度解剖
linux·服务器·网络·算法·边缘计算
bu_shuo1 小时前
MATLAB中的转置操作及其必要性
开发语言·算法·matlab
高洁012 小时前
图神经网络初探(2)
人工智能·深度学习·算法·机器学习·transformer
爱装代码的小瓶子2 小时前
算法【c++】二叉树搜索树转换成排序双向链表
c++·算法·链表
思成Codes2 小时前
数据结构:基础线段树——线段树系列(提供模板)
数据结构·算法
虾..4 小时前
Linux 简单日志程序
linux·运维·算法