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

LeetCode算法日记 - Day 33: 最长公共前缀、最长回文子串

目录

1. 最长公共前缀

1.1 题目解析

1.2 解法

1.3 代码实现

2. 最长回文子串

2.1 题目解析

2.2 解法

2.3 代码实现


1. 最长公共前缀

14. 最长公共前缀 - 力扣(LeetCode)

编写一个函数来查找字符串数组中的最长公共前缀。

如果不存在公共前缀,返回空字符串 ""

示例 1:

输入:strs = ["flower","flow","flight"]
输出:"fl"

示例 2:

输入:strs = ["dog","racecar","car"]
输出:""
解释:输入不存在公共前缀。

提示:

  • 1 <= strs.length <= 200
  • 0 <= strs[i].length <= 200
  • strs[i] 如果非空,则仅由小写英文字母组成

1.1 题目解析

题目本质:
在若干字符串中寻找“所有字符串共同拥有的起始前缀”。等价于:找出最小公共“列”的连续一致部分。

常规解法:
1)把第一个串当基准,从左到右逐列比较;
2)每一列都检查“是否所有字符串在该列字符一致”;
3)一旦某列有人越界或字符不同,前缀到此为止。

问题分析:
最直观做法已是高效思路:每个字符最多被比较一次,因此总比较次数与所有字符串总长度同阶。时间复杂度可以做到 O(S)(S 为全部字符数),空间 O(1)。

思路转折:
如果直接两两比较并把“相同字符累加到全局结果”容易错,正确做法是统一按列比较(纵向扫描),或者维护前缀并逐步截短(水平扫描)。两者复杂度相同,纵向扫描实现更直观、易于避免细节错误。

1.2 解法

算法思想:
设基准串 s0 = strs[0]。对位置 i = 0..s0.length()-1:

  • 取 ch = s0[i];

  • 对每个其他字符串 sj,若 i >= sj.length() 或 sj[i] != ch,则答案为 s0.substring(0, i);

  • 若全部匹配,继续下一个位置。
    若循环结束,返回 s0 本身。

i)边界:若数组为空,返回空串。

ii)外层循环位置 i 遍历基准串每一位。

iii)内层循环字符串索引 j 从 1 到 n-1,检查第 i 位是否存在且相等。

iiii)发现不匹配立即返回前缀;全部通过则最终返回基准串。

易错点:

  • 索引混淆:  内层访问字符必须用 strs[j].charAt(i),而不是 strs[i]...。

  • substring 语义: substring(0, i) 的右端不含 i,当 i == 0 返回空串是正确结果。

  • 空字符串参与: 若某个字符串长度为 0,第一次比较即返回空串。

  • 判空与长度:  数组用 .length,字符串用 .length()。

1.3 代码实现

class Solution {public String longestCommonPrefix(String[] strs) {// 1) 边界处理if (strs == null || strs.length == 0) return "";// 2) 纵向扫描:以第一个字符串为基准,逐列检查for (int i = 0; i < strs[0].length(); i++) {char ch = strs[0].charAt(i);// 与其余字符串在第 i 位统一比较for (int j = 1; j < strs.length; j++) {// 越界或字符不等:i 之前均为公共前缀if (i >= strs[j].length() || strs[j].charAt(i) != ch) {return strs[0].substring(0, i);}}}// 3) 基准串完全通过:它本身就是最长公共前缀return strs[0];}
}

复杂度分析:

  • 时间:O(S),S 为所有字符串总长度(每个位置最多检查一次)。

  • 空间:O(1) 额外空间(只用常数级变量)。

2. 最长回文子串

5. 最长回文子串 - 力扣(LeetCode)

给你一个字符串 s,找到 s 中最长的 回文 子串。

示例 1:

输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。

示例 2:

输入:s = "cbbd"
输出:"bb"

提示:

  • 1 <= s.length <= 1000
  • s 仅由数字和英文字母组成

2.1 题目解析

题目本质:
在字符串中找到“关于某一中心左右对称”的最长连续子串。回文子串可由一个“中心”向两侧对称扩展得到:奇数长度中心为 (i,i),偶数长度中心为 (i,i+1)。

常规解法:
暴力枚举所有子串再判断是否回文:两重循环确定区间、再线性判断。

问题分析:
暴力法需要枚举 O(n^2) 个区间,每次校验 O(n),最坏 O(n^3),n=1000 时不够高效。

思路转折:
要想高效 → 利用“回文围绕中心对称”的性质,只需枚举中心并向两侧扩展

  • 每个中心向外扩的总步数受限于 n,因此总体最坏 O(n^2);

  • 实现简单、无额外空间;

  • 面试与刷题的主流解法(更快的 O(n) Manacher 可作为进阶)。

2.2 解法

解法

算法思想:
对每个位置 i

  • 以 (i,i) 作为奇数回文中心扩展,得到长度 len1 = r1-l1-1;

  • 以 (i,i+1) 作为偶数回文中心扩展,得到长度 len2 = r2-l2-1;

  • 取更长者更新答案起点 begin = L+1 与长度 len。
    扩展结束条件:越界或两侧字符不等。

i)特判:空串或长度 1 直接返回。

ii)初始化 begin=0,len=0。

iii)遍历中心 i = 0..n-1:

  • 令 l=i,r=i,while 两侧相等则扩展;根据 right-left-1 更新答案;

  • 令 l=i,r=i+1,同理扩展并比较更新。

iiii)返回 s.substring(begin, begin+len)(右端开区间)。

易错点:

  • 区间边界:扩展结束时下标已越过合法区间,真正回文是 (left+1, right-1),长度为 right-left-1;最终 substring 用 [begin, begin+len)。

  • 奇/偶中心都要尝试:只试一种会漏解。

  • 变量遮蔽:没必要定义类字段 left/right,用方法内局部变量即可,避免混淆。

2.3 代码实现

class Solution {public String longestPalindrome(String s) {int n = s.length();if (n < 2) return s; // 长度为 0/1,自己就是最长回文int begin = 0, len = 1; // 至少有 1 个字符时,单字符是回文for (int i = 0; i < n; i++) {// 奇数中心 (i, i)int l = i, r = i;while (l >= 0 && r < n && s.charAt(l) == s.charAt(r)) { l--; r++; }if (r - l - 1 > len) {begin = l + 1;len = r - l - 1;}// 偶数中心 (i, i+1)l = i; r = i + 1;while (l >= 0 && r < n && s.charAt(l) == s.charAt(r)) { l--; r++; }if (r - l - 1 > len) {begin = l + 1;len = r - l - 1;}}return s.substring(begin, begin + len);}
}

复杂度分析

  • 时间:最坏 O(n^2)(每个中心向外扩总步数受限于 n)。

  • 空间:O(1) 额外空间。


文章转载自:

http://NI8bgjFb.rhdqz.cn
http://NnKVAFAC.rhdqz.cn
http://7CQmokgB.rhdqz.cn
http://Y13srBeH.rhdqz.cn
http://GDXl9ufm.rhdqz.cn
http://1DMY6Eh5.rhdqz.cn
http://b9oDz5cn.rhdqz.cn
http://ANQ9TwqC.rhdqz.cn
http://LG5ck2L5.rhdqz.cn
http://dlrII7Eo.rhdqz.cn
http://91WbLMTI.rhdqz.cn
http://DlXoFIkN.rhdqz.cn
http://Kcqml6PQ.rhdqz.cn
http://C9TQNsd1.rhdqz.cn
http://SYkST75H.rhdqz.cn
http://X05Wevwb.rhdqz.cn
http://w3fKsl9F.rhdqz.cn
http://eqhNYatg.rhdqz.cn
http://4ZtISeAv.rhdqz.cn
http://828zy9jV.rhdqz.cn
http://l3K6NsKA.rhdqz.cn
http://CRgsduM5.rhdqz.cn
http://Wqp7fJyP.rhdqz.cn
http://TmiB8vH0.rhdqz.cn
http://SALbwrZ3.rhdqz.cn
http://KR9T1aWk.rhdqz.cn
http://43tmzv4m.rhdqz.cn
http://7Soc1uY2.rhdqz.cn
http://uIkrap8Y.rhdqz.cn
http://jtStUDAK.rhdqz.cn
http://www.dtcms.com/a/370075.html

相关文章:

  • 能发弹幕的简单视频网站
  • 【开题答辩全过程】以 基于Hadoop电商数据的可视化分析为例,包含答辩的问题和答案
  • 苍穹外卖优化-续
  • vi中的常用快捷键
  • 如何使显示器在笔记本盖上盖子时还能正常运转
  • 09_多态
  • 用 Go + HTML 实现 OpenHarmony 投屏(hdckit-go + WebSocket + Canvas 实战)
  • 《sklearn机器学习——聚类性能指标》Silhouette 系数
  • 什么是CSS
  • 【FastDDS】 Entity Policy 之 标准Qos策略
  • `IntersectionObserver`延迟加载不在首屏的自动播放视频/图片/埋点/
  • 笔记:ubuntu安装matlab
  • [linux仓库]性能加速的隐形引擎:深度解析Linux文件IO中的缓冲区奥秘
  • 【Redis】--持久化机制
  • 机器人控制器开发(导航算法——导航栈关联坐标系)
  • Linux系统编程守护进程(36)
  • 基于STM32单片机的酒驾检测设计
  • CodeBuddy 辅助重构:去掉 800 行 if-else 的状态机改造
  • Paimon——官网阅读:文件系统
  • 数据仓库概要
  • 【C++上岸】C++常见面试题目--算法篇(第二十期)
  • PyTorch生成式人工智能——深度分层变分自编码器(NVAE)详解与实现
  • Whismer-你的定制化AI问答助手
  • Paimon——官网阅读:配置
  • FPGA会用到UVM吗?
  • 电脑外接显示屏字体和图标过大
  • 深入浅出 HarmonyOS ArkUI 3.0:基于声明式开发范式与高级状态管理构建高性能应用
  • 如何在路由器上配置DHCP服务器?
  • 计算机网络:网络设备在OSI七层模型中的工作层次和传输协议
  • Unity 如何使用ModbusTCP 和PLC通讯