14.最长公共前缀
解题思路
/**
* @author : icehill
* @description : 最长公共前缀
* 编写一个函数来查找字符串数组中的最长公共前缀。
* <p>
* 如果不存在公共前缀,返回空字符串 ""。
* 示例 1:
* 输入:strs = ["flower","flow","flight"]
* 输出:"fl"
* 示例 2:
* 输入:strs = ["dog","racecar","car"]
* 输出:""
* 解释:输入不存在公共前缀。
* 提示:
* 0 <= strs.length <= 200
* 0 <= strs[i].length <= 200
* strs[i] 仅由小写英文字母组成
* <p>
* 来源:力扣(LeetCode)
* 链接:https://leetcode-cn.com/problems/longest-common-prefix
* 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
* 解题思路
* 1我的方法(官方称纵向扫描)
* 对于数组strs,从0开始依次判断数组元素的每个字符strs[j].charAt[i]是否一致
* 结束条件:
* 1.数组strs有一个字符的长度<i
* 2.第i轮中有一个字符窗strs[j],strs[j].charAt[i]与基准对照组的字符不一致
* 时间复杂度:O(mn) 空间复杂度:O(1)其中 m 是字符串数组中的字符串的平均长度,n 是字符串的数量
* <p>
* 2.横向扫描
* 对于字符串s1 s2 s3 …… sn,寻找最长公共前缀,
* 相当于取s1 s2的公共前缀x,再寻找x s3 …… sn的公共前缀
* 直到x为空或者到达sn
* 时间复杂度:O(mn) 空间复杂度:O(1)
* <p>
* 3.分治
* 对于问题LCP(s1 s2 ……sn)可以分解为求LCP(x1 x2)
* x1=LCP(s1…… sk)
* x2=LCP(sk+1…… sn)
* 时间复杂度:O(mn)空间复杂度:O(mlogn),
* 4.二分查找
* 最长公共前缀的长度不会超过字符串数组中的最短字符串的长度。用 minLength
* 表示字符串数组中的最短字符串的长度,
* 则可以在 [0,minLength] 的范围内通过二分查找得到最长公共前缀的长度。
* 每次取查找范围的中间值 mid,判断每个字符串的长度为 mid 的前缀是否相同,
* 如果相同则最长公共前缀的长度一定大于或等于 mid,如果不相同则最长公共前缀的长度一定小于 mid,
* 通过上述方式将查找范围缩小一半,直到得到最长公共前缀的长度。
* 时间复杂度:O(mnlogm)空间复杂度:O(1)
* @date : 2021-04-11
*/
public class Solution14 {
public static void main(String[] args) {
Solution14 solution14 = new Solution14();
String[] strs = {"flower", "flow", "flight"};
// String[] strs = {"ab", "a"};
System.out.println(solution14.longestCommonPrefix(strs));
}
public String longestCommonPrefix(String[] strs) {
if (strs == null || strs.length == 0) {
return "";
}
int maxLength = 0;
for (int i = 0; i < strs[0].length(); i++) {
int j = 1;
for (; j < strs.length; j++) {
//如果j大于其中一个字符串的长度,则停止
if (i >= strs[j].length()) {
break;
}
if (strs[j].charAt(i) != strs[0].charAt(i)) {
break;
}
}
//j != strs.length 也就是对于第i个字符,数组strs没有全部元素的第i个字符一样
if (j != strs.length) {
break;
}
maxLength++;
}
return maxLength > 0 ? strs[0].substring(0, maxLength) : "";
}
}