[leetCode]14.最长公共子串

在这里插入图片描述

解法一: 横向扫描(暴力匹配)

可以使用第一个字符串与第二个字符串进行最长公共子串的匹配,再用这个最长公共子串和后面的字符串进行匹配,如果匹配到的子串为空,则最长公共子串一定为空。

class Solution {
    public String longestCommonPrefix(String[] strs) {
        if(strs == null || strs.length == 0) {
            return "";
        }
        String prefix = strs[0];
        for(int i = 1; i < strs.length; i++){
            prefix = longestCommonPrefix(prefix, strs[i]);
            if(prefix.length() == 0)break;
        }
        return prefix;
    }
    public String longestCommonPrefix(String prefix, String str){
        int index = 0;
        int length = Math.min(prefix.length(), str.length());
        while(index < length && prefix.charAt(index) == str.charAt(index)){
            index++;
        }
        return prefix.substring(0,index);
    }
}

解法二 分治

主要思想:把字符串数组分为左右两个子问题,分别进行求解,再求两个子问题解的最长前缀。
在这里插入图片描述

class Solution {
    public String longestCommonPrefix(String[] strs) {
        if(strs == null || strs.length == 0) return "";
        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 leftLCP = longestCommonPrefix(strs,start, mid);
            String rightLCP = longestCommonPrefix(strs,mid + 1, end);
            return commonPrefix(leftLCP, rightLCP);
        }
    }

    public String commonPrefix(String l, String r){
        int index = 0;
        int len = Math.min(l.length(), r.length());
        while(index < len && l.charAt(index) == r .charAt(index)){
            index++;
        }
        return l.substring(0,index);
    }
}

解法三 二分查找法

字符串数组的最大前缀由字符串数组中的最短字符串决定因此

  • 先计算最短字符串的长度
  • 对字符数组第一个字符串进行二分查找
    如果前半部分属于最长前缀则丢弃前半部分,继续查找后半部分
    如果前半部分不属于前缀,则丢弃后半部分,继续查找前半部分
class Solution {
    public String longestCommonPrefix(String[] strs) {
        if(strs == null || strs.length == 0) return "";
        int minLen = strs[0].length();//最短字符串的长度
        for(String each : strs){
            minLen = each.length() < minLen ? each.length() : minLen;
        }
        int low = 0, high = minLen;

        while(low <= high){
            int mid = (low + high)/2;
            if(isCommonPrefix(strs,mid)){
                low = mid + 1;
            }else{
                high = mid -1;
            }
        }
        return strs[0].substring(0,(low + high)/2);
    }

    public boolean isCommonPrefix(String[] strs, int mid){
        String subStr = strs[0].substring(0,mid);
        for(int i = 0; i < strs.length; i++){
            for(int j = 0; j < subStr.length(); j++){
                if(strs[i].charAt(j) != subStr.charAt(j))return false;
            }
        }
        return true;
    }
}

解法四 纵向扫描

在这里插入图片描述

  • 字符串数组左对齐按行排列
  • 按列纵向进行遍历判断下一个字符串第i列的字符是否等于第一行第i列的字符
    如果不相等则返回子串
    如果i等于当前行的长度则返回子串
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(strs[j].charAt(i)!=c || strs[j].length() == i){
                    return strs[0].substring(0,i);
                }
            }
        }
        return strs[0];
    }
}

参考

https://leetcode-cn.com/problems/longest-common-prefix/solution/zui-chang-gong-gong-qian-zhui-by-leetcode-solution/

posted @ 2020-06-15 17:35  消灭猕猴桃  阅读(205)  评论(0编辑  收藏  举报