「这是我参与2022首次更文挑战的第32天,活动详情查看:2022首次更文挑战」。
题目描述:
14. 最长公共前缀 - 力扣(LeetCode) (leetcode-cn.com)
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 ""。
示例一
输入: strs = ["flower","flow","flight"]
输出: "fl"
示例二
输入: strs = ["dog","racecar","car"]
输出: ""
解释: 输入不存在公共前缀。
提示:
1 <= strs.length <= 2000 <= strs[i].length <= 200strs[i]仅由小写英文字母组成
思路分析
纵向扫描
找公共前缀,最直觉的解法就是纵向对比每一列了,这里借用下官解的一张图,很简单,我就懒得自己画了。
通过纵向对比的去更新答案。
AC代码
class Solution {
public String longestCommonPrefix(String[] strs) {
if (strs == null || strs.length == 0) {
return "";
}
int length = strs[0].length();
int count = strs.length;
for (int i = 0; i < length; i++) {
char c = strs[0].charAt(i);
for (int j = 1; j < count; j++) {
if (i == strs[j].length() || strs[j].charAt(i) != c) {
return strs[0].substring(0, i);
}
}
}
return strs[0];
}
}
分治思想
这次二刷本题,再想一个解法,这个在第一个的基础上也是很容易想到的优化方案。
所谓分治,就是分开找公共前缀,然后得出的公共前缀的公共前缀就是答案。
官解 中说了一堆的公式,但还是图更容易理解些。
AC代码
class Solution {
fun longestCommonPrefix(strs: Array<String>): String {
return longestCommonPrefix(strs, 0, strs.size-1)
}
fun longestCommonPrefix(strs: Array<String>, start:Int, end:Int): String {
if(start == end) return strs[start]
val mid = (start+end)/2
val left = longestCommonPrefix(strs,start,mid)
val right = longestCommonPrefix(strs,mid+1,end)
val minLength = Math.min(left.length, right.length)
for(i in 0 until minLength) {
if(left[i] != right[i]) {
return left.substring(0,i)
}
}
return left.substring(0, minLength)
}
}
总结
分治虽然看起来比较简单,但是实现起来还是有点小麻烦的,这个分治就演变成了递归,我们需要找到递归结束的条件。
参考
最长公共前缀 - 最长公共前缀 - 力扣(LeetCode) (leetcode-cn.com)
14. 最长公共前缀 (分治思想) - 最长公共前缀 - 力扣(LeetCode) (leetcode-cn.com)
4种解题思路,每种注释详细,思路清晰 - 最长公共前缀 - 力扣(LeetCode) (leetcode-cn.com)