Loading

Easy | LeetCode 14. 最长公共前缀 | 二分法

14. 最长公共前缀

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

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

示例 1:

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

示例 2:

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

提示:

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

解题思路

方法一:纵向扫描

如下图

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];
}

方法二:分治算法

public String longestCommonPrefix(String[] strs) {
    if (strs == null || strs.length == 0) {
        return "";
    } else {
        return longestCommonPrefix(strs, 0, strs.length - 1);
    }
}

public String longestCommonPrefix(String[] strs, int start, int end) {
    if (start == end) {
        return strs[start];
    } else {
        int mid = (end - start) / 2 + start;
        String lcpLeft = longestCommonPrefix(strs, start, mid);
        String lcpRight = longestCommonPrefix(strs, mid + 1, end);
        return commonPrefix(lcpLeft, lcpRight);
    }
}

public String commonPrefix(String lcpLeft, String lcpRight) {
    int minLength = Math.min(lcpLeft.length(), lcpRight.length());       
    for (int i = 0; i < minLength; i++) {
        if (lcpLeft.charAt(i) != lcpRight.charAt(i)) {
            return lcpLeft.substring(0, i);
        }
    }
    return lcpLeft.substring(0, minLength);
}

方法三:二分查找

public String longestCommonPrefix(String[] strs) {
    if (strs == null || strs.length == 0) {
        return "";
    }
    int minLength = Integer.MAX_VALUE;
    for (String str : strs) {
        minLength = Math.min(minLength, str.length());
    }
    int low = 0, high = minLength;
    // 二分法找最大的公共前缀
    while (low < high) {
        int mid = (high - low + 1) / 2 + low;
        if (isCommonPrefix(strs, mid)) {
            // 如果mid处是相同的, 则往右找
            low = mid;
        } else {
            // 如果不是相同的, 则往左找
            high = mid - 1;
        }
    }
    return strs[0].substring(0, low);
}

public boolean isCommonPrefix(String[] strs, int length) {
    // str0 代表第一个字符串
    String str0 = strs[0].substring(0, length);
    int count = strs.length;
    // 遍历后面的每一个字符串
    for (int i = 1; i < count; i++) {
        String str = strs[i];
        // 从字符串的首个字符逐个向后扫描, 看是否和第一个字符串的字符是相同的。
        for (int j = 0; j < length; j++) {
            if (str0.charAt(j) != str.charAt(j)) {
                return false;
            }
        }
    }
    return true;
}
posted @ 2021-02-27 15:48  反身而诚、  阅读(142)  评论(0编辑  收藏  举报