14. 最长公共前缀

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

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

示例 1:

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

示例 2:

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

提示:

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

算法:
纵向扫描,从前往后遍历所有字符串的每一列,比较相同列上的字符是否相同,如果相同则继续对下一列进行比较,如果不相同则当前列不再属于公共前缀,当前列之前的部分为最长公共前缀。

14_fig.png

代码:

class Solution {
    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];
    }
}

复杂度分析:

  • 时间复杂度:O(mn),其中 m 是字符串数组中的字符串的平均长度,n 是字符串的数量。最坏情况下,字符串数组中的每个字符串的每个字符都会被比较一次。
  • 空间复杂度:O(1)。使用的额外空间复杂度为常数。

5. 最长回文子串

给你一个字符串 s,找到 s 中最长的回文子串。

示例 1:

输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。

示例 2:

输入:s = "cbbd"
输出:"bb"

提示:

1 <= s.length <= 1000
s 仅由数字和英文字母组成

算法:

对于一个子串而言,如果它是回文串,并且长度大于 2,那么将它首尾的两个字母去除之后,它仍然是个回文串。例如对于字符串“ababa”,如果我们已经知道“bab” 是回文串,那么 “ababa” 一定是回文串,这是因为它的首尾两个字母都是“a”。

5_fig1.png
5_fig2.png

代码:

class Solution {
    public String longestPalindrome(String s) {
        int len = s.length();
        //长度小于2的直接就是回文串了
        if (len<2){
            return s;
        }
        //保存起始位置和最大长度
        int begin = 0;
        int maxLen = 1;

        //dp[i][j] == true 表示子串 i 到 j 是回文串
        //如果dp[i][j]是回文串则 (dp[i+1][j-1] || j-i<3)&& s[i]==s[j]
        boolean[][] dp = new boolean[len][len];
        //长度为1的子串是回文串
        for (int i = 0; i < len; i++) {
            dp[i][i]=true;
        }
        char[] chars = s.toCharArray();

        // 由于 i <= j 故只用填dp表的上三角,一列一列的填
        for (int j = 1; j < len; j++) {//dp表的列遍历
            for (int i = 0; i < len; i++) {//dp表的行遍历
         //如果dp[i][j]是回文串则 (dp[i+1][j-1] || j-i<3)&& s[i]==s[j]
                if (chars[i]!=chars[j]){
                    dp[i][j]=false;
                }else {
                    if (j-i<3){
                        dp[i][j]=true;
                    }else {
                        dp[i][j]=dp[i+1][j-1];
                    }
                }
        //更新最长回文串 初始位置和长度
                if (dp[i][j] && j-i+1>maxLen){
                    maxLen=j-i+1;
                    begin=i;
                }
            }
        }
        return s.substring(begin,begin+maxLen);
    }
}

复杂度分析:

  • 时间复杂度:O(n^2),其中 nn 是字符串的长度。动态规划的状态总数为 O(n^2),对于每个状态,我们需要转移的时间为 O(1)。
  • 空间复杂度:O(n^2),即存储动态规划状态需要的空间。
最后修改:2022 年 12 月 20 日
如果觉得我的文章对你有用,请随意赞赏