
Day 3 继续推进。
今天的两道题一个偏 字符串回文处理,一个偏 模拟构造。
难度看起来不像昨天那样“硬”,但这两题非常适合练基本功:如何从规律中写出干净代码。
今天的关键词是:中心扩散、规律模拟、边界处理。
🧠 LeetCode 5 – Longest Palindromic Substring
💡 思路总结
这题要求找到字符串中的最长回文子串。
最直接的思路不是暴力枚举所有子串,而是:
👉 以每个位置为中心,向两边扩散
因为回文串有两种情况:
- 奇数长度回文:中心是一个字符
- 偶数长度回文:中心是两个字符之间
所以每次遍历到下标 i 时,要做两次扩展:
expand(s, i, i)expand(s, i, i + 1)
⚡ 核心点
- 回文的本质:左右字符相等
- 每个位置都可能成为回文中心
- 用辅助函数统一处理扩展逻辑,代码更清晰
💻 代码实现
class Solution {
public:
string longestPalindrome(string s) {
if (s.empty()) return "";
int start = 0, maxLen = 1;
for (int i = 0; i < s.size(); i++) {
expand(s, i, i, start, maxLen); // 奇数长度
expand(s, i, i + 1, start, maxLen); // 偶数长度
}
return s.substr(start, maxLen);
}
void expand(string& s, int left, int right, int& start, int& maxLen) {
while (left >= 0 && right < s.size() && s[left] == s[right]) {
if (right - left + 1 > maxLen) {
maxLen = right - left + 1;
start = left;
}
left--;
right++;
}
}
};
📌 知识点总结
1️⃣ 中心扩展法
相比暴力枚举所有子串,这种方法更自然:
- 枚举中心
- 向两边扩展
- 实时更新最长长度
时间复杂度是 O(n^2),空间复杂度是 O(1)。
2️⃣ 回文串的两种中心
这题最容易漏掉的点就是:
"aba"是奇数回文"abba"是偶数回文
所以一定要写两次扩展。
3️⃣ 辅助函数思想
把“扩散逻辑”单独写成 expand,好处很明显:
- 主函数更清晰
- 逻辑复用
- 更不容易写乱
这也是以后写题时很值得保留的习惯。
🔀 LeetCode 6 – Zigzag Conversion
💡 思路总结
这题本质不是数学题,而是一个规律模拟题。
可以把字符串字符按“之”字形一行一行放进去:
- 往下走
- 到底后往上走
- 到顶后再往下走
最后把每一行拼接起来,就是答案。
⚡ 核心点
- 用
vector<string>存每一行 - 用
currow表示当前行号 - 用
dir表示方向:1表示向下-1表示向上
当走到顶部或底部时,方向反转。
💻 代码实现
class Solution {
public:
string convert(string s, int numRows) {
if(numRows == 1)return s;
vector <string> rownums(numRows); //申请一个向量字符串 rownums[0]=""......rownums[numRows-1]="".
int currow = 0;
int dir = -1;
for(char a : s){ //字符串的遍历;
rownums[currow] += a;
if(currow == 0 || currow == numRows -1){
dir = -dir;
}
currow += dir;
}
//这一段实现了currow的上下摆动 :0->1->2->1->0,
string result;
for (string row : rownums){
result += row;
}
return result;
}
};
📌 知识点总结
1️⃣ 模拟题的关键:找到状态量
这题最重要的不是死算,而是抓住两个状态:
- 当前在哪一行
currow - 当前方向是什么
dir
只要这两个量维护好了,整个过程就顺了。
2️⃣ 边界触发方向变化
当满足:
currow == 0 || currow == numRows - 1
说明走到了最上面或者最下面,这时候就要调头。
这就是这题的“规律核心”。
3️⃣ 特殊情况别漏
if(numRows == 1) return s;
这个判断非常关键。
因为只有一行时,根本不会发生“之字形摆动”,直接返回原字符串即可。
🧩 今日总结
| 题目 | 核心思想 |
|---|---|
| LeetCode 5 | 中心扩展 + 回文判断 |
| LeetCode 6 | 模拟 + 方向控制 |
今天这两题虽然不像 LeetCode 4 那样抽象,但很锻炼代码表达能力:
- 你要会把规律拆出来
- 你要会把重复逻辑抽成函数
- 你要会处理边界,不让代码出错
这些能力,后面写中等题和困难题都会一直用到。
🧠 今日收获
今天可以重点记住两个模型:
回文串问题
可以优先想:
- 中心扩展
- 动态规划
而这题里,中心扩展已经是非常经典、非常实用的方法。
模拟题
可以优先想:
- 当前状态是什么
- 状态如何转移
- 什么时候改变方向 / 规则
很多看着花里胡哨的题,本质就是“状态模拟”。
💬 写给自己的话
Day 3 了。
你已经不是“随便刷两题试试”的状态了,
你是在一题一题地积累自己的题感。
也许现在做题还是会慢,
也许有些题还需要看题解,
但这不丢人。
真正重要的是:
你没有停。
刷题这件事,最怕的不是不会,
最怕的是三天热度。
而你现在做的,就是一点一点把“会做题”变成自己的能力。
继续写,继续练,继续总结。
总有一天,你会发现自己已经比刚开始强太多了。
阿玉,继续冲。
—— 刷题第 3 天
