前言:

记录一下对左程云系列算法课程--算法讲解066【必备】的剩余习题的学习。本文主要简单记录个人学习心得和提供C++版本代码。如需要题目的细致讲解,请前往原视频。

涉及内容:

动态规划、三指针、

参考视频:

左程云--算法讲解066【必备】从递归入手一维动态规划


题目列表:

1.Leetcode--264. 丑数 II
2.Leetcode--32. 最长有效括号
3.Leetcode--467. 环绕字符串中唯一的子字符串
4.Leetcode--940. 不同的子序列 II

题目解答:

⭐1.Leetcode--264. 丑数 II
题目:

解题思考:

首先可以很好的考虑到暴力求解,我们只需要从1开始,从大到小每个数字遍历判断其是否是丑数然后计数即可,但很显然这会超时。

那么我们从质因子入手,因为一个丑数(除1)外,都是由其他丑数×2 | 3 | 5 得到的,那么我们可以从1出发,会得到三个丑数:2、3、5,所以1后面的丑数就是2。接着从2出发,得到三个丑数:4、6、10,算上之前得到但是没有使用的丑数一共是:3、4、5、6、10,所以2后面的数字应该是3,之后循环即可。从上述思路知道我们需要一个优先队列(最小堆),关于C++中priority_queue的比较器我在这里由所记录,按需观看。

可以优先队列会随着时间的推移而变大,而且在得到最终结果时,有很多用不到的数据也会被一直存储。例如刚才我们求第三个丑数(3)时已经计算了5个数。

通过观察,我们可以只保存三个变量,分别指代*2、*3、*5,当对应变量被使用时,我们只需要改变这一个变量即可,即优化了优先队列的空间,还对比较的数据范围进行缩小化。

三版的示例代码如下。

示例代码:

①暴力(超时)

class Solution {
public:int nthUglyNumber(int n) {int count = 0;int num = 0;while(count < n){num++;if(isUglyNumber(num)){count++;} }//count == nreturn num;}bool isUglyNumber(int n){if(n <= 0){return false;}while(n % 2 == 0){n /= 2;}while(n % 3 == 0){n /= 3;}while(n % 5 == 0){n /= 5;}if(n == 1){return true;}return false;}
};

②优先队列(最小堆)

class Solution {
private:struct compare{bool operator()(unsigned long long a, unsigned long long b){return a > b;}};
public:int nthUglyNumber(int n) {priority_queue<unsigned long long, vector<unsigned long long>, compare> pq;unsigned long long num = 1;int count = 1;while(count != n){count++;pq.push((unsigned long long)num * 2);pq.push((unsigned long long)num * 3);pq.push((unsigned long long)num * 5);num = pq.top();while(num == pq.top()){pq.pop();}}return num;}
};

③三指针动态规划

class Solution {
public:int nthUglyNumber(int n) {vector<int> dp(n + 1, 0);dp[1] = 1;int i2 = 1, i3 = 1, i5 = 1;for(int i = 2; i <= n; i++){int a = dp[i2] * 2;int b = dp[i3] * 3;int c = dp[i5] * 5;dp[i] = min(min(a, b), c);if(dp[i] == a) { i2++; }if(dp[i] == b) { i3++; }if(dp[i] == c) { i5++; }}return dp[n];}
};
辅助题目与示例代码:

这里再推荐一些相关习题,只是和本题相关,与动态规划无关。

①Leetcode--231. 2 的幂
class Solution {
public:bool isPowerOfTwo(int n) {return n > 0 && (n & (n - 1)) == 0;}
};
②Leetcode--263. 丑数
class Solution {
public:bool isUgly(int n) {if(n <= 0){return false;}while(n % 3 == 0){n /= 3;}while(n % 5 == 0){n /= 5;}return n > 0 && (n & (n - 1)) == 0;}
};
⭐2.Leetcode--32. 最长有效括号
题目:

解题思考:

本题的动态规划做法中存在着KMP算法的影子。首先对于暴力求解,我们只需要枚举以每一位为结尾的子括号串的有效括号串长度,最后求最大值即可。但很显然这存在重复计算,那么如何利用之前已经计算过的数据,这就是该题动态规划做法的来历。、

如果当前位置为左括号"(",很显然依此结尾的字串不可能有效,对应dp数组我们记作0。

如果当前位置为右括号")",我们可以看dp[i - 1]位置对应的有效字串长度是多少,这个时候我们只需要关注p = i - dp[i - 1] - 1这个位置是否为"("。如果是,则可以在dp[i - 1]的基础上再加上两个字符长度。最后判断dp[p - 1]位置有多长的有效字符串长度,再次加上即可。

此时只需要加到dp[p - 1]即可,再左边就不用看了,因为我们按照顺序求解,dp[p - 1]的值已经是最长的有效字符串长度了。

 这里还是推荐一下原视频的,左老师模拟了一个很长的例子帮助有效理解,最后代码如下。

示例代码:
class Solution {
public:int longestValidParentheses(string s) {if (s == "") { return 0; }int n = s.size();vector<int> dp(n, 0);dp[0] = 0;int ans = 0;for(int i = 1; i < n; i++){if(s[i] == ')'){int p = i - dp[i - 1] - 1;if(p >= 0 && s[p] == '('){dp[i] = dp[i - 1] + 2 + (p > 0 ? dp[p - 1] : 0);}}ans = max(ans, dp[i]);}return ans;}
};
⭐3.Leetcode--467. 环绕字符串中唯一的子字符串
题目:

解题思考:

最容易想到的暴力解法当然是逐个位置进行枚举,显然,重复计算非常多。而观察可发现长字符串是包含短字符串的,所以很自然可以联系到状态方程。但这里重点不在如何建立状态方程,状态方程只是"果"。我们要找的是字串之间的关系,即"因"。

如果我们以每个位置作为字串的开头去判断是否为有效字串,则从0位置开始显然是最复杂的,那么这时可以考虑从末位置,即从右向左,但这可能写不顺手。所以我们可以使每个位置作为字串的结尾,从左向右即可。

那么从0位置入手,很显然其对应的字串为1。在下一个位置时,我们查看上一个位置是否能连在一起构成有效字串,如果是有效字串,则以此位置结尾的有效字串最大长度为len+ 1,len用于记录当前有效字串最大长度,而我们对26个字母都存放对应字母结尾时,可以构成的有效子串个数,最后循环完毕累加即可。可能表述不是很清楚,这里还是推荐一下左老师的原视频。

示例代码:
class Solution {
public:int findSubstringInWraproundString(string s) {int n = s.size();vector<int> ss(n);for(int i = 0; i < n; i++){ss[i] = s[i] - 'a';}vector<int> dp(26, 0);int len = 1;dp[ss[0]] = 1;for(int i = 1, cur, pre; i < n; i++){cur = ss[i];pre = ss[i - 1];if((pre == 25 && cur == 0) || pre + 1 == cur){len++;}else{len = 1;}dp[cur] = max(dp[cur], len);}int ans = 0;for(int x : dp){ans += x;}return ans;}
};
⭐4.Leetcode--940. 不同的子序列 II
题目:

解题思考:

 本题还是看原视频吧。主要特点在于计数和去重,cnt[idx]设计的很好。

示例代码:
class Solution {
private:int mod = 1e9 + 7;
public:int distinctSubseqII(string s) {vector<int> cnt(26, 0);int all = 1;int newAdd;for(char c : s){int idx = c - 'a';newAdd = (all - cnt[idx] + mod) % mod;cnt[idx] = (cnt[idx] + newAdd) % mod;all = (all + newAdd) % mod;}return (all - 1 + mod) % mod;}
};

最后:

关于动态规划的总结其实左老师也讲了很多。这节课最重要的学习了动态规划是怎样来的,即设计纯递归、记忆化搜索、设计递推、空间优化。其实整个过程也就是把递归写成迭代的做法。另外还有对序列的操作,作为初学者的我也很容易将每个位置所为所求序列的开头,但是这样会陷入0位置就是最复杂位置的困难。当我们反向思考,让每个位置最为所求序列的结尾,这样就可以从0位置起依次迭代了。

学习算法是漫长且痛苦的过程,且可能长期伴随着焦虑。但这是始终要面对的,毕竟是自己选择的路。算法难吗?难。需要天赋吗?需要一点。自己有天赋没?不知道。在我看来,天赋只有在经历过无数努力且踩在巨人的肩膀上才能体现的东西。更何况天赋的高山永无顶点,只要实现自我超越,就是有价值的。愿自己能在学习技术和算法的路上一直走下去。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/913967.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/913967.shtml
英文地址,请注明出处:http://en.pswp.cn/news/913967.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【理念●体系】Windows AI 开发环境搭建实录:六层架构的逐步实现与路径治理指南

【理念●体系】从零打造 Windows WSL Docker Anaconda PyCharm 的 AI 全链路开发体系-CSDN博客 Windows AI 开发环境搭建实录&#xff1a;六层架构的逐步实现与路径治理指南 ——理念落地篇&#xff0c;从路径规划到系统治理&#xff0c;打造结构化可复现的 AI 开发环境 AI…

5G标准学习笔记15 --CSI-RS测量

5G标准学习笔记15 --CSI-RS测量 前言 前面讲了&#xff0c;在5GNR中&#xff0c;CSI-RS 是支持信道状态评估、波束管理和无线资源管理&#xff08;RRM&#xff09;的关键参考信号。下面孬孬基于3GPP TS 38.331中的内容&#xff0c;详细定义了基于 CSI-RS 的测量程序&#xff0c…

第P28:阿尔茨海默病诊断(优化特征选择版)

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 一、进阶说明 针对于特征对模型结果的影响我们做了特征分析 特征选择 1. SelectFromModel 工作原理&#xff1a;基于模型的特征选择方法&#xff0c;使用…

AI的欧几里得要素时刻:从语言模型到可计算思维

引言 人工智能正在经历一个关键的转折点。就像欧几里得的《几何原本》为数学奠定了公理化基础一样&#xff0c;AI也正在寻找自己的"要素时刻"——一个能够将当前的语言模型能力转化为真正可计算、可验证思考的转变。 最近发表的论文《AI’s Euclid’s Elements Momen…

番外-linux系统运行.net framework 4.0的项目

基础环境&#xff1a;linux系统&#xff0c;.net framework 4.0&#xff0c;npgsql 2.2.5.0 &#xff08;版本不同&#xff0c;构建可能失败&#xff09; 方法背景&#xff1a;linux不支持运行.net framework 4.0&#xff0c;高版本mono不支持npgsql 2.x 主要使用&#xff1a…

国内AI训练都有哪些企业?:技术深耕与场景实践

国内AI训练都有哪些企业&#xff1f;当人工智能从实验室走向产业一线&#xff0c;AI 训练就像为智能系统 “施肥浇水” 的关键环节&#xff0c;让技术根系在各行业土壤里扎得更深。国内一批 AI 训练企业正各展所长&#xff0c;有的专攻技术优化&#xff0c;有的深耕场景应用。它…

微算法科技基于格密码的量子加密技术,融入LSQb算法的信息隐藏与传输过程中,实现抗量子攻击策略强化

随着量子计算技术的发展&#xff0c;传统加密算法面临被量子计算机破解的风险&#xff0c;LSQb 算法也需考虑应对未来可能的量子攻击。微算法科技基于格密码的量子加密技术&#xff0c;融入LSQb算法的信息隐藏与传输过程中&#xff0c;实现抗量子攻击策略强化。格密码在面对量子…

xAI发布Grok4+代码神器Grok4 Code,教你如何在国内升级订阅SuperGrok并使用到Grok4教程

就在今天&#xff0c;马斯克旗下xAI发布了其最新的旗舰AI模型Grok4&#xff0c;并同步推出专为开发者打造的编程利器 Grok 4 Code&#xff0c;还推出了一项全新的AI订阅计划——每月300美元的SuperGrokHeavy。 那最新发布的Grok4以及有哪些特性呢&#xff1f;以及如何才能使用…

Rust 变量遮蔽(Variable Shadowing)

在 Rust 中&#xff0c;变量遮蔽&#xff08;Variable Shadowing&#xff09; 是一种在同一作用域内重新声明同名变量的特性。它允许你创建一个新变量覆盖之前的同名变量&#xff0c;新变量与旧变量类型可以不同&#xff0c;且旧变量会被完全隐藏。核心特点允许同名变量重复声明…

【VScode | 快捷键】全局搜索快捷键(ctrl+shift+f)失效原因及解决方法

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f60e;金句分享&#x1f60e;&a…

Windows 与 Linux 内核安全及 Metasploit/LinEnum 在渗透测试中的综合应用

目录 &#x1f6e0;️ 1. 内核安全如何助力渗透测试与黑客行业 1.1 内核安全的战略价值 1.2 结合 Metasploit 与 LinEnum 的作用 &#x1f50d; 2. Metasploit 信息收集模块及其在内核安全中的应用 2.1 Windows 信息收集模块 2.2 Linux 信息收集模块 2.3 使用步骤 Wind…

京东携手HarmonyOS SDK首发家电AR高精摆放功能

在电商行业的演进中&#xff0c;商品的呈现方式不断升级&#xff1a;从文字、图片到视频&#xff0c;再到如今逐渐兴起的3D与AR技术。作为XR应用探索的先行者&#xff0c;京东正站在这场体验革新的最前沿&#xff0c;不断突破商品展示的边界&#xff0c;致力于通过创新技术让消…

瞄准Win10难民,苹果正推出塑料外壳、手机CPU的MacBook

最近有消息称&#xff0c;苹果正在研发一款定位“低价”的MacBook&#xff0c;售价可能低于800美元&#xff08;约合人民币5800元&#xff09;&#xff0c;采用的是A18 Pro芯片&#xff0c;也就是未来iPhone 16 Pro同款的“手机芯片”&#xff0c;而不是现有的M系列。这款产品预…

原子级 macOS 信息窃取程序升级:新增后门实现持久化控制

臭名昭著的 Atomic macOS Stealer&#xff08;AMOS&#xff0c;原子级 macOS 窃取程序&#xff09;恶意软件近期完成危险升级&#xff0c;全球 Mac 用户面临更严峻威胁。这款与俄罗斯有关联的窃密程序首次植入后门模块&#xff0c;使攻击者能维持对受感染系统的持久访问、执行远…

Shader面试题100道之(81-100)

Shader面试题&#xff08;第81-100题&#xff09; 以下是第81到第100道Shader相关的面试题及答案&#xff1a; 81. Unity中如何实现屏幕空间的热扭曲效果&#xff08;Heat Distortion&#xff09;&#xff1f; 热扭曲效果可以通过GrabPass抓取当前屏幕图像&#xff0c;然后在片…

C#洗牌算法

洗牌算法是一种将序列&#xff08;如数组、列表&#xff09;元素随机打乱的经典算法&#xff0c;核心目标是让每个元素在打乱后出现在任意位置的概率均等。在 C# 中&#xff0c;常用的洗牌算法有Fisher-Yates 洗牌算法&#xff08;也称 Knuth 洗牌算法&#xff09;&#xff0c;…

Python PDFplumber详解:从入门到精通的PDF处理指南

一、PDFplumber核心优势解析 在数字化办公场景中&#xff0c;PDF文档处理是数据分析师和开发者的必备技能。相较于PyPDF2、pdfminer等传统库&#xff0c;PDFplumber凭借其三大核心优势脱颖而出&#xff1a; 精准表格提取&#xff1a;采用流式布局分析算法&#xff0c;支持复杂表…

Flutter 与 Android 的互通几种方式

Flutter 与 Android 的互通主要通过以下几种方式实现&#xff0c;每种方式适用于不同的场景&#xff1a;1. 平台通道&#xff08;Platform Channels&#xff09; Flutter 与原生 Android 代码通信的核心方式&#xff0c;支持双向调用。 类型&#xff1a; MethodChannel&#xf…

全新开源AI知识库系统!PandaWiki一键构建智能文档,支持AI问答、创作与搜索!

传统 Wiki 工具像一本厚重的“死书”&#xff0c;虽能存储信息&#xff0c;却无法主动「思考」。而在当今AI席卷各个行业的浪潮中&#xff0c;知识管理也迎来了智能化的巨大飞跃。最近开源圈悄然走红的 PandaWiki&#xff0c;就用 AI 大模型为知识库注入了 灵魂&#xff0c; 它…

Rust 结构体

Rust 结构体 引言 Rust 是一种系统编程语言,以其内存安全、并发支持和零成本抽象而闻名。结构体(struct)是 Rust 中用于创建自定义数据类型的工具。本文将深入探讨 Rust 结构体的概念、用法以及其在实际编程中的应用。 结构体的定义 在 Rust 中,结构体是一种复合类型,…