LeetCode高频题14:最长公共前缀
提示:本题是系列LeetCode的150道高频题,你未来遇到的互联网大厂的笔试和面试考题,基本都是从这上面改编而来的题目
互联网大厂们在公司养了一大批ACM竞赛的大佬们,吃完饭就是设计考题,然后去考应聘人员,你要做的就是学基础树结构与算法,然后打通任督二脉,以应对波云诡谲的大厂笔试面试题!
你要是不扎实学习数据结构与算法,好好动手手撕代码,锻炼解题能力,你可能会在笔试面试过程中,连题目都看不懂!比如华为,字节啥的,足够让你读不懂题
题目
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 “”。
一、审题
示例 1:
输入:strs = [“flower”,“flow”,“flight”]
输出:“fl”
示例 2:
输入:strs = [“dog”,“racecar”,“car”]
输出:“”
解释:输入不存在公共前缀。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/longest-common-prefix
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
非常简单的遍历对比,没啥算法优化技能
就是暴力对比,绕不开的
第一个字符串拿出来s
跟剩下的挨个暴力对比,看看位置i到哪匹配不了,i=4没法匹配上,或者越界了停止对比,退出,
将i赋值给min当做最小的匹配不上的位置
下一次,拿着s跟另一个字符串暴力对比,发现i=2就没法对比了,将i赋值给min做最小无法匹配的位置。
一旦所有的字符串全部对比完成,则min就是最小那个没法公共匹配上的位置,s的0–min-1位置就是最小的能匹配的公共字符串
史称最长公共子串……
手撕代码:
//左神没讲之前,我用前缀树做的,太复杂了…………
//其实很简单:复习:
public static String longestCommonPrefix(String[] strs) {
if (strs == null || strs.length == 0) return "";
if (strs.length == 1) return strs[0];
//超过俩
//第一个字符串拿出来s
String s = strs[0];
int N = strs.length;
int minIndex = Integer.MAX_VALUE;
for (int i = 1; i < N; i++) {
//跟剩下的挨个暴力对比,看看位置i到哪匹配不了,i=4没法匹配上,或者越界了停止对比,退出,
int index = 0;//从头开始,暴力找
while (index < s.length() && index < strs[i].length()){
if (s.charAt(index) != strs[i].charAt(index)) break;//一旦匹配不了,失败退出
index++;//依次往下找
}
minIndex = Math.min(minIndex, index);将i赋值给min当做最小的匹配不上的位置
}
//最后最长公共前缀就是s:0--minIndex-1
return s.substring(0, minIndex);
}
测试:
public static void test(){
Solution solution = new Solution();
String[] strs = {"abab","aba","abk"};
String res = solution.longestCommonPrefix(strs);
System.out.println(res);
String ans = longestCommonPrefix(strs);
System.out.println(ans);
}
public static void main(String[] args) {
test();
}
问题不大:
ab
ab
LeetCode测试:
还有一种简单写法
那个最长公共子串,一定是别人的前缀
咱就随便找一个串res,
拿着跟所有字符串都比一遍,res不是所有串的前缀,那么它需要缩屁股一个字符
这种做法也是跟上面一样的
直到res是所有的串的前缀,它必然是最长公共子串
//上面那俩都不行,
public String longestCommonPrefix(String[] strs) {
//再想办法优化优化
//再次遇到了subString这个自带函数,很重要!!,截取一段字符串
if (strs.length == 0) return "";
//反正随便选一个,最长公共子串都有在内,拿他整个串开始比,不行,就缩一个位置
String res = strs[0];
//所有的字符串,挨个比
for(String s:strs){
while (!s.startsWith(res)){
//每个字符串比一下,它的前缀如果不是res,则需要res缩
if (res.length() == 0) return "";//一旦出现""就没必要比了
res = res.substring(0, res.length() - 1);
}
}
return res;
}
虽然我用前缀树也搞通了,但是没意思,太复杂了,不是遇到前缀字符串就必须用前缀树
也没通,不管,你看上面就行
总结
提示:重要经验:
1)最长公共前缀,一定它是所有字符串的开头
2)这种暴力对比,找到最小那个无法跟所有字符串匹配的位置,往前就是所有字符串都能配上的最长公共前缀
3)笔试求AC,可以不考虑空间复杂度,但是面试既要考虑时间复杂度最优,也要考虑空间复杂度最优。