当前位置: 首页 > news >正文

【贪心算法】day2

📝前言说明:

  • 本专栏主要记录本人的贪心算法学习以及LeetCode刷题记录,按专题划分
  • 每题主要记录:(1)本人解法 + 本人屎山代码;(2)优质解法 + 优质代码;(3)精益求精,更好的解法和独特的思想(如果有的话);(4)贪心策略正确性的 “证明”
  • 文章中的理解仅为个人理解。如有错误,感谢纠错

🎬个人简介:努力学习ing
📋本专栏:C++刷题专栏
📋其他专栏:C语言入门基础,python入门基础,C++学习笔记,Linux
🎀CSDN主页 愚润泽

你可以点击下方链接,进行其他贪心算法题目的学习

点击链接开始学习
贪心day1贪心day2
贪心day3贪心day4
贪心day5贪心day6
贪心day7贪心day8
贪心day9贪心day10

也可以点击下面连接,学习其他算法

点击链接开始学习
优选专题动态规划
递归、搜索与回溯贪心算法

题目

  • 179. 最大数
    • 优质解
    • 证明
  • 376. 摆动序列
    • 优质解
  • 300. 最长递增子序列
    • 优质解


179. 最大数

题目链接:https://leetcode.cn/problems/largest-number/description/
在这里插入图片描述


优质解

思路:

  • 该题其实就是一个排序问题,排序问题本质是:选择两个数,然后按规则决定两个数的先后顺序
  • 本题:对于ab,我们尝试获得 abba 的组合,哪个组合大,则为正确的排序(这就是本题的贪心策略)
  • 然后,sort的时候按我们的规则排序即可

细节:

  • 我们可以先把数字转换成字符串,然后拼接字符串,比较字典序
  • 全为 0 的特殊情况

代码:

class Solution {
public:string largestNumber(vector<int>& nums) {vector<string> strs;for(auto x: nums) strs.emplace_back(to_string(x));auto rule = [](const string& s1, const string& s2){return s1 + s2 > s2 + s1; // 返回true代表优先级高};sort(strs.begin(), strs.end(), rule);string ans = "";for(auto s: strs)ans += s;return ans[0] == '0'? string("0") : ans;}
};

时间复杂度O(k⋅nlogn)O(k⋅nlogn)O(knlogn),k 为字符串平均长度,拼接操作时间复杂度为 O(k)O(k)O(k)
空间复杂度: O(nk)O(nk)O(nk)

证明

来自Leetcode官方题解答案:
在这里插入图片描述


376. 摆动序列

题目链接:https://leetcode.cn/problems/wiggle-subsequence/description/
在这里插入图片描述


优质解

思路:

  • 贪心策略:以序列结束位置为基准,每次只考虑下一个元素是否会让此序列变得更长
  • 下一个位置有两种情况 >< ,代表两个不同状态结尾的序列
  • >up 序列的是在前一个 down 序列的长度上 +1,如果出现连续的 >,只会 +1 一次(正确性保证 1)
  • 因为我们始终记录了两种状态的序列(即:全部状态),并且每次都是在原来最优解的基础上+1,所以每次的局部最优就是全局最优

代码:

class Solution {
public:int wiggleMaxLength(vector<int>& nums) {int n = nums.size();if(n == 1) return 1;int up = 1, down = 1;for(int i = 1; i < nums.size(); i++){if(nums[i] > nums[i - 1])up = down + 1;if(nums[i] < nums[i - 1])down = up + 1;}return max(up, down);}
};

时间复杂度:O(n)O(n)O(n)
空间复杂度:O(1)O(1)O(1)


300. 最长递增子序列

题目链接:https://leetcode.cn/problems/longest-increasing-subsequence/description/
在这里插入图片描述


优质解

思路:

贪心 + 二分

  • 回想动态规划:如果新插入的数字比原来最长子序列的最后一个数字大,则可以接入(所以我们只关注子序列的最后一个元素和新插入的元素的大小)
  • end[i] 表示:长度为 i 的子序列的最后一个元素的大小
  • 每次插入数时,用二分查找找到最佳的插入位置
    • 如果可以接在目前最长的子序列后面,则代表:变得更长
    • 如果不能,则可能更新(变小)前面某一子序列的结尾的数

代码:

class Solution {
public:int lengthOfLIS(vector<int>& nums) {int n = nums.size();vector<int> end; // end[i]: 长度为 i 的序列的结尾的元素end.push_back(nums[0]);for(int i = 1; i < n; i++){if(nums[i] > end.back())end.push_back(nums[i]);else{// 二分查找int left = 0, right = end.size() - 1;while(left < right){int mid = (left + right) >> 1;if(end[mid] < nums[i])left = mid + 1;elseright = mid;}end[left] = nums[i];}} return end.size();}
};

时间复杂度:O(nlogn)O(nlogn)O(nlogn)
空间复杂度:O(n)O(n)O(n)


🌈我的分享也就到此结束啦🌈
要是我的分享也能对你的学习起到帮助,那简直是太酷啦!
若有不足,还请大家多多指正,我们一起学习交流!
📢公主,王子:点赞👍→收藏⭐→关注🔍
感谢大家的观看和支持!祝大家都能得偿所愿,天天开心!!!

http://www.dtcms.com/a/349087.html

相关文章:

  • Golang云端编程入门指南:前沿框架与技术全景解析
  • 初探机器学习:从概念定义到前沿应用
  • 湖南(源点咨询)市场调研如何在行业研究中快速有效介入(尾篇)
  • mpv - write_video 流程解析
  • 从技术精英到“芯”途末路:一位工程师的沉沦与救赎
  • 暖色调街头人像摄影照片Lr调色教程,手机滤镜PS+Lightroom预设下载!
  • OpenHarmony Audio子系统全栈解码:从HDI驱动到DSP算法的低延迟高保真之路
  • SQL Server缩小日志文件.ldf的方法(适用于开发环境)
  • 复杂水域场景识别率↑89%!陌讯多模态融合算法在岸边垃圾检测的落地实践
  • Python学习笔记之(二)变量和简单的数据类型
  • 鸿蒙中Image白块问题分析与解决方案
  • Java:HashMap的使用
  • 2025/8/24 DockerDesktop安装使用
  • 云原生俱乐部-RH294知识点归纳(3)
  • Python内置函数全解析:30个核心函数语法、案例与最佳实践指南
  • Linux应急响应一般思路(二)
  • C++测试框架高级资源管理模块完整实现指南
  • 八、redis 入门 之 雪崩、穿透、击穿
  • 小米AX3600访问桥接的光猫
  • 如何一键统一文件名大小写?
  • Springboot框架的“上海迪士尼”旅游管理网站设计与开发
  • C++---双指针
  • 工作后的总结和反思3
  • cookie,session,token之间有什么关系
  • 大模型知识--Function Calls
  • Kubernetes — 学习 Sidecar 容器模式
  • 面经-自用
  • CVPR 2025 | 医学影像加速进化:深度学习×多模态,精准诊断再升级
  • Transformer 模型详解:从自注意力到编码器-解码器结构
  • 拓展:simulink中将仿真环境离散化