-
今日打卡宣言(1-2句,保持真诚) Day 2,坚持住了!昨天发完第一篇后有点小成就感,今天项目虽然忙,但还是挤时间把这道经典题手写了一遍。继续拒绝温水煮青蛙,冲!
-
LeetCode 部分 代码
中等
相关标签
相关企业
提示
给你一个字符串 s,找到 s 中最长的 回文 子串。
示例 1:
输入: s = "babad"
输出: "bab"
解释: "aba" 同样是符合题意的答案。
示例 2:
输入: s = "cbbd"
输出: "bb"
提示:
1 <= s.length <= 1000s仅由数字和英文字母组成- 题目链接:leetcode.cn/problems/lo…
- 难度:中等
- 时间复杂度目标:O(n²)(中心扩展法)
- 核心思路(简短3行): 回文串以单个字符或两个字符为中心,向两边扩展检查是否相同。遍历每个可能中心(2n-1个),扩展到最大,记录最长长度和起始位置。
- 代码(Go 版本,中心扩展法,最常用也最易懂):
Go
func longestPalindrome(s string) string {
if len(s) < 2 {
return s
}
start, maxLen := 0, 1 // 至少长度1
// 扩展函数:从 left/right 向两边扩展
expand := func(left, right int) (int, int) {
for left >= 0 && right < len(s) && s[left] == s[right] {
left--
right++
}
return left + 1, right - 1 // 回退一步是有效边界
}
for i := 0; i < len(s); i++ {
// 奇数长度回文(以i为中心)
l, r := expand(i, i)
if r-l+1 > maxLen {
start = l
maxLen = r - l + 1
}
// 偶数长度回文(以i和i+1为中心)
l, r = expand(i, i+1)
if r-l+1 > maxLen {
start = l
maxLen = r - l + 1
}
}
return s[start : start+maxLen]
}
- C++ 版本(如果你想双语放一个简短的):
C++
string longestPalindrome(string s) {
if (s.size() < 2) return s;
int start = 0, maxLen = 1;
auto expand = [&](int l, int r) {
while (l >= 0 && r < s.size() && s[l] == s[r]) { --l; ++r; }
return make_pair(l+1, r-1);
};
for (int i = 0; i < s.size(); ++i) {
auto [l1, r1] = expand(i, i);
if (r1 - l1 + 1 > maxLen) { start = l1; maxLen = r1 - l1 + 1; }
auto [l2, r2] = expand(i, i+1);
if (r2 - l2 + 1 > maxLen) { start = l2; maxLen = r2 - l2 + 1; }
}
return s.substr(start, maxLen);
}
-
易错点/优化点:
- expand 时 left-- 和 right++ 要在 while 判断前执行?不对,要在循环里先判断再移动。
- 边界:left >=0 && right < len(s) 必须同时检查。
- 面试追问:怎么优化到 O(n)?(Manacher 算法,但今天先掌握中心扩展)
- 空间:O(1),很好!
-
知识点部分(今天配 Go slice 陷阱,超实用) Go slice 常见陷阱 & 面试高频
- append 时容量不足会重新分配(通常翻倍),导致旧 slice 底层数组可能被新 slice 共享。
- 示例 bug:
Go
a := []int{1, 2, 3}
b := a[:2] // b = [1,2], 底层数组共享
b = append(b, 4) // 如果容量够,a 也会变成 [1,2,4,3]!!
- 正确做法:想独立 → b := append([]int{}, a[:2]...) 或 copy
- 面试常问:slice 是值传递还是引用?(值传递,但底层数组指针,所以修改元素会影响原 slice)
- 容量 vs 长度:cap(s) 和 len(s) 区别,append 后 cap 可能变大。
- 今日感悟(最打动人的一段) 这道题以前觉得“简单”,今天从头写中心扩展才发现边界条件超级多(奇偶、起始位置记录、expand 里的 left/right 回退)。公开打卡逼着我必须跑通测试用例,不能蒙混。感觉每多写一行代码,就离舒适区远一点。继续坚持!
- 结束语 明天见! 欢迎评论区:① 分享你的最长回文子串写法 ② 指出我代码哪里还能优化 ③ 说说你最近刷题的痛点 #程序员打卡 #LeetCode #Go语言 #最长回文子串