今日题目

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

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

示例 1:

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

示例 2:

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

提示:

1 <= strs.length <= 200 0 <= strs[i].length <= 200 strs[i] 仅由小写英文字母组成

思路

公共最长前缀的特点: 前缀必然存在每一个字符串。

使用第一个字符串与其他字符串进行逐一对比得出前缀长度;并且所有长度取最小值就是题解

可优化的点:

  1. 公共前缀不会超过任意一个字符串的长度,不用每次都比较整个字符串,只要比较当前的前缀长度即可
  2. 如果没有公共前缀,那么不需要遍历剩余的字符串

实现

public String longestCommonPrefix(String[] strs) {
    if (strs.length == 0) {
        return "";
    }
    // 最长前缀末尾位置
    int end = strs[0].length() - 1;
    for (int i = 1; i < strs.length; i++) {
        // 优化1: 不用比较整个字符串, 只要比较前缀长度即可
        int j = 0;
        for (; j <= end && j < strs[i].length(); j++) {
            if (strs[0].charAt(j) != strs[i].charAt(j)) {
                //如果第一个字符都不相等,就不用比较了
                if(j == 0){
                    return "";
                }
                break;
            }
        }
        end = Math.min(end, j - 1);
    }
    return strs[0].substring(0, end + 1);
}

执行用时:1 ms, 在所有 Java 提交中击败了70.59%的用户

内存消耗:36.3 MB, 在所有 Java 提交中击败了89.59%的用户

解法二

第二种解法其实和第一种是一样的思想,只不过可以利用String的api方法

startWith()方法,有了这个方法可以使代码实现更加优雅

 public String longestCommonPrefix(String[] strs) {
     if (strs.length == 0) {
         return "";
     }
     // 最长前缀
     String commonPrefix = strs[0];
     for (int i = 1; i < strs.length; i++) {
         while (!strs[i].startsWith(commonPrefix)) {
             if (commonPrefix.length() == 0) {
                 return "";
             }
             commonPrefix = commonPrefix.substring(0, commonPrefix.length() - 1);
         }
     }
     return commonPrefix;
 }

执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户

内存消耗:36.5 MB, 在所有 Java 提交中击败了44.26%的用户

小结

这两天的题目相对来说比较简单,但是能够一次完全写对还是有难度的,需要多注意常用的api写法

比如:

  • map的循环方式,entry的写法
  • String的常用api,比如substring(start, end)注意不是驼峰, 区间是左闭右开**[start, end)**
  • 字符串和链表获取串长度是方法ss.length(),而数组的是变量array.length
  • 数字与字符串之间的互转,String.valueOf(int), Integer.parseIn(string)这个方法不会频繁拆箱装箱
  • 而且做题有注意审题,这道题我刚开始还以为是找最长公共子串