继续用「快刷四部曲」把 78 题(最长公共前缀)5 分钟秒掉。
(模板记忆点:① 纵向扫描;② 一旦失配立即 return;③ 空数组特护。)
① 抽象模型
k 个字符串,求从左端开始的最长公共子串。
等价于:对第 0 列、第 1 列...逐列检查,直到某一列字符不全相同或某个字符串已经到头。
② 最优算法
时间:O(totalLen) 所有字符最多被看一次。
空间:O(1) 原地比对。
算法:
- 特护:strs == null || strs.length == 0 → return ""
- 令 minLen = 最短字符串长度
- 逐列 col = 0 ... minLen-1
- 取 strs[0].charAt(col) 作为基准
- 遍历 i = 1...k-1,若 strs[i].charAt(col) ≠ 基准 → 立即 return strs[0].substring(0, col)
- 循环结束 return strs[0].substring(0, minLen)
③ 边界/异常
- 空数组 ⇒ ""
- 含空串 ⇒ ""
- 仅一个字符串 ⇒ 它自身
④ 代码(Java,可直接粘 LintCode)
java
public String longestCommonPrefix(String[] strs) {
if (strs == null || strs.length == 0) return "";
int minLen = Integer.MAX_VALUE;
for (String s : strs) minLen = Math.min(minLen, s.length());
for (int col = 0; col < minLen; col++) {
char c = strs[0].charAt(col);
for (int i = 1; i < strs.length; i++) {
if (strs[i].charAt(col) != c) {
return strs[0].substring(0, col);
}
}
}
return strs[0].substring(0, minLen);
}
复杂度:
时间 O(∑len),空间 O(1)。
写完,Submit,一遍 AC。