每日一道算法面试题(17):leecode 14 最长公共前缀

1.算法题目

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

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

示例 1:

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

示例 2:

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

说明:
所有输入只包含小写字母 a-z 。

2.算法思路

首先总结一下公共前缀的规律,所谓字符串的公共前缀,指的是不同的字符串相同位置上的字符都相等的最大子字符串。借助这个规律得出的算法思路如下:

  1. 逐位比较:首先找出最短的字符串长度(因为最长公共前缀的长度不会大于最短字符串的长度),然后遍历字符串数组从前到后每个位置上面的字符是否相等,遍历到都相等时记录公共前缀;
  2. 水平扫描:从前往后枚举字符串的每一列,先比较每个字符串相同列上的字符(即不同字符串相同下标的字符)然后再进行对下一列的比较。

3.算法代码

根据逐位比较的算法思路编写的算法代码如下:

    public String longestCommonPrefix(String[] strs) {
        if (strs == null || strs.length == 0) {
            return "";
        }
        // 1.找出最短的字符串长度
        int minLength = strs[0].length();
        for (int i = 1; i < strs.length; i ++) {
            if (minLength > strs[i].length()) {
                minLength = strs[i].length();
            }
        }
        if (minLength == 0) {
            return "";
        }
        String prevStr = "";
        for (int i = 0; i < minLength; i ++) {
            char c = strs[0].charAt(i);
            int j = 1;
            for (; j < strs.length; j ++) {
                if (c != strs[j].charAt(i)) { // 只需要比较相同位置的字符是否相等,若比较字符串时间复杂度会变高,效率降低
                    break;
                }
            }
            if (j < strs.length) {
                break;
            }
            prevStr = strs[0].substring(0, i + 1);
        }
        return prevStr;
    }

根据水平扫描的算法思路编写的算法代码如下:

    public String longestCommonPrefix(String[] strs) {
        if (strs == null || strs.length == 0) {
            return "";
        }
        for (int i = 0; i < strs[0].length(); i ++) {
            char c = strs[0].charAt(i);
            for (int j = 1; j < strs.length; j ++) {
                if (i == strs[j].length() || c != strs[j].charAt(i)) {
                    return strs[0].substring(0, i);
                }
            }
        }
        return strs[0];
    }

4.总结

这个算法有一点需要注意的是一定要比较相同位置上的字符,而不是比较所有前缀都被字符串包含。

如果你有疑问或更好的算法思路,欢迎留言交流!!!

你可能感兴趣的:(面试题,算法题,编程学习)