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

C++ 模拟 力扣1576. 替换所有的问号 题解 每日一题

文章目录

  • 模拟算法
    • 模拟到底是什么?—— 算法界的“按图索骥”
    • 解题思路
    • 模拟算法的意义:别小看“照着做”,它是算法的“地基”
    • 模拟算法做题策略:先保证“做对”,再追求“做好”
  • 题目描述
  • 为什么这道题值得练?
  • 算法原理
  • 代码实现时的细节
    • 核心问题:怎么判断字母能不能用?
  • 代码实现
  • 总结
  • 下题预告

在这里插入图片描述
在这里插入图片描述

模拟算法

模拟到底是什么?—— 算法界的“按图索骥”

提起算法,很多人第一反应是“动态规划的复杂状态”“贪心的精妙选择”,但模拟算法偏偏是个“异类”——它不玩花活,核心就俩字:照着来

你可以把它理解成“按食谱做饭”:题目已经把“要做什么、步骤是什么”明明白白告诉你了,比如“先切菜、再倒油、最后炒5分钟”,你的任务不是琢磨“能不能换个菜谱”,而是把“切菜要切多碎、油热到什么程度”这些细节落地成代码。

所以模拟算法的“简单”,是思路上的“好想”——只要读明白题,脑子里基本就有流程了;但它的“难”,藏在代码的“落地能力”里:比如边界有没有漏、细节有没有错、逻辑有没有绕晕 😵。

解题思路

很多朋友也包括我做模拟题的经常会出现的误区:读题的时候觉得“哦这简单”,直接上手写代码,结果写着写着就卡壳——要么漏了某个条件,要么处理错了边界,往往最后还是要落实在纸面上,步入最开始就一步一步写出来。

其实模拟题的解题思路就藏在题目描述里,但一定要加一步:把思路“画”出来。不管是在草稿纸上写流程,还是在电脑上用注释列步骤,哪怕是像小学生做题一样“逐句翻译”题目,都能帮你避开80%的坑。

举个例子:如果题目说“把字符串里的问号换成字母,不能和前后重复”,别要光想“换a就行吧?”,而是要写清楚:

  1. 遍历字符串,遇到问号才处理🚩;
  2. 处理问号时,得看左边的字符是什么(如果有的话) 👈;
  3. 还要看右边的字符是什么(如果有的话)👉;
  4. 选一个既不等于左边、也不等于右边的字母填上✅。

这一步看似“麻烦”,但写代码时会顺风顺水——因为你相当于把“脑子里的模糊想法”变成了“清晰的执行步骤”💡。

模拟算法的意义:别小看“照着做”,它是算法的“地基”

我刚学算法时,也偷偷质疑过:“模拟这玩意儿也算算法?不就是把题目翻译成代码吗?” 🤔

直到后来做了更难的题才明白:所有复杂算法,本质都是“更高级的模拟”。比如动态规划,是在模拟“状态转移的过程”;贪心算法,是在模拟“每一步选最优的决策”;甚至图论里的BFS,也是在模拟“一层一层遍历节点的过程”。

如果连“简单题的模拟”都写得磕磕绊绊,遇到“需要拆解、抽象、优化的复杂模拟题”只会更懵。比如有些模拟题需要你先选合适的数据结构(用数组还是队列?),再处理海量边界(比如时间格式转换里的“月份有没有31天”“闰年2月多一天”),还要优化效率(比如避免双重循环超时)——这些能力,都是从“简单模拟”里练出来的。

所以别觉得模拟“low”,它是帮你打通“算法思路”和“代码实现”的关键一步。

模拟算法做题策略:先保证“做对”,再追求“做好”

模拟题在笔试里很常见,尤其是作为“热身题”或“中档题”出现。这时候的核心目标是:在最短时间内AC,别纠结“代码好不好看”

分享我自己的做题流程,亲测高效:

  1. 读题划重点:用笔画出题目里的“必须满足的条件”(比如“不能连续重复”“不能修改非问号字符”)和“边界情况”(比如“字符串长度为1”“问号在开头/结尾”);
  2. 草稿纸模拟示例:拿题目给的示例(比如示例1的“?zs”),在纸上一步步走流程——比如“第一个字符是问号,右边是z,所以填a就行”;
  3. 写代码先搭框架:先写最核心的逻辑(比如遍历字符串、遇到问号进入循环),再补细节(比如判断左右字符);
  4. 测试边界用例:写完后别直接提交,自己造几个极端情况测一测——比如输入是“?”(只有一个问号)、输入是“???”(全是问号)、输入是“a?b?c”(问号在中间),确保这些情况都能跑对。

记住:笔试里“AC”比“代码优雅”重要一万倍——哪怕你用了三层循环(只要不超时),只要能过所有测试用例,就是好代码👍。

题目描述

题目链接:力扣1576. 替换所有的问号

题目描述:
给你一个仅包含小写英文字母和 '?' 字符的字符串 s,请你将所有的 '?' 转换为若干小写字母,使最终的字符串不包含任何 连续重复 的字符。
注意:你 不能 修改非 '?' 字符。
题目测试用例保证 除 '?' 字符 之外,不存在连续重复的字符。
在完成所有转换(可能无需转换)后返回最终的字符串。如果有多个解决方案,请返回其中任何一个。可以证明,在给定的约束条件下,答案总是存在的。

示例 1:
输入:s = “?zs”
输出:“azs”
解释:该示例共有 25 种解决方案,从 “azs” 到 “yzs” 都是符合题目要求的。只有 “z” 是无效的修改,因为字符串 “zzs” 中有连续重复的两个 ‘z’ 。

示例 2:
输入:s = “ubv?w”
输出:“ubvaw”
解释:该示例共有 24 种解决方案,只有替换成 “v” 和 “w” 不符合题目要求。因为 “ubvvw” 和 “ubvww” 都包含连续重复的字符。

提示:
1 <= s.length <= 100
s 仅包含小写英文字母和 ‘?’ 字符

为什么这道题值得练?

这道题是模拟题的“标准模板”,它完美覆盖了模拟题的核心考点:常规逻辑处理 + 边界情况判断。既不用我们想复杂的算法,又能帮我们练“代码细节把控”,还有就是这道题算是奖励题嘻嘻😄。

而且它的场景很贴近笔试:难度不高,但容易因为漏细节翻车(比如忘了处理“问号在开头”的情况),练会这道题,能帮你避开很多同类坑。

算法原理

我们直接来一步一步的模拟
1.一般情况(示例2为例,问号在中间)
如图所示👇:
在这里插入图片描述
2.边界情况(问号在开头/结尾)
在正常的模拟的时候我们要注意自己去找一找边界情况,有的时候题目的示例不会给你边界情况,即?在字符串第一个和最后一个的时候(以示例1为例)
如下图👇:
在这里插入图片描述
同理最右侧也相同

代码实现时的细节

我们在做模拟时的追求是,用最少的代码,实现最快的代码,其实这也是我们学习算法的追求。
所以这道题的几个细节单独提炼出来分析,在做题的时候这一部也很重要。

核心问题:怎么判断字母能不能用?

首先我们模拟填入字母一定是按照a~z的顺序填入的无非就是一个循环,但是在判断左右这里,我们是通过什么方法来又省时间又省空间呢?
我真实的思路是用哈希表,最开始是想用if判断写但是因为没有将所有的条件写出来(脑子里面想的是又要处理边界情况,又要判断前面又要判断后面的)下意识就直接用了哈希……

在实现出来之后发现代码又长又臭❌

  • 为了存两个可能存在的字符,特意开了个哈希表,纯属浪费空间;
  • 插入哈希表、判断是否存在,这些操作虽然简单,但完全没必要;
  • 本质上就是“为了处理两个条件,却用了一个复杂的数据结构”。
    真的是简单问题复杂做。

分析判断条件有哪些

  1. 关于左边:

    • 如果是第一个字符(i=0),左边没有字符 → 不用判断左边;
    • 否则,必须保证新字母 ≠ 左边的字符(j != s[i-1])。
  2. 关于右边:

    • 如果是最后一个字符(i = s.size()-1),右边没有字符 → 不用判断右边;
    • 否则,必须保证新字母 ≠ 右边的字符(j != s[i+1])。

列出来之后突然发现:这不就是四个简单的条件吗?而且可以用“或(||)”和“与(&&)”组合起来!

左边的判断可以写成:i == 0 || j != s[i-1](要么是开头,要么不等于左边);
右边的判断可以写成:i == s.size()-1 || j != s[i+1](要么是结尾,要么不等于右边);
两个条件都满足,就可以用这个字母:

((i == 0 || j != s[i - 1]) && (i == s.size() - 1 || j != s[i+1]))

就这么这么一个简单的判断,完全能替代哈希表的功能,还更高效、更简洁。✨

==反思:为什么会绕远路?==🤯
后来我想了想,当时之所以会想到用哈希表,其实是因为:

  • 面对“多种情况”时,第一反应是“用工具去包容所有情况”,而不是“用逻辑去简化条件”;
  • 没耐心先拆解问题,总想着“赶紧写代码试错”,结果越走越偏。

所以做模拟题时,真的别急着写代码——先在纸上把逻辑理清楚,往往能少走很多弯路。就像这道题,看似复杂的条件,其实用一个if判断就能解决。

代码实现

class Solution {
public:string modifyString(string s) {// 遍历字符串的每个字符for(int i = 0; i < s.size(); i++){// 只处理问号if(s[i] == '?'){// 从a到z试字母,找到能用的就填for(char j = 'a'; j <= 'z'; j++){// 核心判断:既不跟左边重复,也不跟右边重复(处理边界)if((i == 0 || j != s[i - 1]) && (i == s.size() - 1 || j != s[i + 1])){s[i] = j; // 填上能用的字母break;    // 找到就退出,不用再试其他字母}}}}return s; // 返回处理后的字符串}
};

这段代码的优点:

  • 没有多余的数据结构(比如哈希表),空间复杂度O(1);
  • 判断条件简洁,一眼能看懂;
  • 从a开始试字母,保证能找到答案(题目说答案存在)。

总结

做模拟题,别追求“炫技”,记住三个关键词:

  1. 画流程 🖍️:别光靠脑子想,把步骤写在纸上/注释里;
  2. 抓边界 🚫:注意“开头/结尾”“空值”“极值”这些容易漏的情况;
  3. 简判断 ✂️:能用一个条件搞定的,别拆成多个if-else,既省代码又不容易错。

练会这些,你面对大部分模拟题都能游刃有余。

下题预告

下一篇我们来练一道“稍微复杂点的模拟题”——提莫攻击🎮。玩英雄联盟的朋友命该很熟悉这道题,它需要我们先“理解中毒时间的计算逻辑”,再转化成代码,能帮我们进一步提升“拆解问题”的能力,感兴趣的朋友可以先去看看题目哦~

力扣 495. 提莫攻击

如果这篇内容对你有帮助,别忘了 点赞👍 + 收藏⭐ + 关注👀 哦!
有问题欢迎在评论区留言,我会认真思考并及时回复!

在这里插入图片描述

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

相关文章:

  • 安全联盟网站认证网络营销的认识
  • 基于SpringBoot+Vue的少儿编程培训机构管理系(WebSocket及时通讯、协同过滤算法、Echarts图形化分析)
  • 时序数据库promQL
  • 网站安全检测可以监测哪些内容风险信息宜春网站开发
  • 网站建设中企动力强成都那家网站建设好
  • RK3588 linux在uboot关机模式下待熄屏休眠后拔插适配器无反应屏幕也不会亮
  • 建设厅网站关于建筑资质合并wordpress速度很慢
  • 做网站的叫什么软件上海阿里巴巴做网站
  • Redis的Hash解析
  • 旅游业网站开发建设毕设做微课资源网站设计可以吗
  • 设计公司网站什么重要杭州工业设计
  • 【北京迅为】iTOP-4412精英版使用手册-第三十五章 WEB控制LED
  • 重庆seo整站优化报价福建建筑人才网官网
  • 教学信息化大赛网站建设作品永久免费国外ip代理
  • [嵌入式系统-93]: NVIDIA 正在从‘数据中心霸主’向‘端-边-云一体化AI平台’战略扩张。
  • 网站管理助手4.0域名备案查询管理系统
  • Oracle EBS ERP之报表开发—条件筛选按钮和组件开发
  • 济南网站建设与优化注册城乡规划师考试时间2023
  • 南通网站建设公司做品牌推广用什么网站
  • linux模拟压测CPU彪高到100%
  • 【2025全新】CDToolX专业圆二色谱数据处理软件下载安装教程(含最新版安装包)
  • 做网站做小程序推广中搜seo
  • Qiankun 微前端框架 start() 方法详解
  • 网站开发服务器多少钱个体户45万以下免个税
  • Autoware Universe 定位模块详解 | 第二节 深入研究定位模块数据流
  • 网站底部横条导航代码免费软件app下载大全
  • Java程序员如何深入学习JVM底层原理?
  • 送上门卤菜网站要怎么做软文代写发布网络
  • 有关网站建设的app安徽省建设工程质量协会网站
  • 【Liunx】高级IO