14. Longest Common Prefix

题目描述(简单难度)

在这里插入图片描述
编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀,返回空字符串 “”。

解法一 垂直比较

Java

思路:我们首先判定给定数组中长度最小的元素,然后按照这个min(length),将数组中元素依次进行比较,如果比较成功返回True,不成功则返回Fasle.

public String longestCommonPrefix(String[] strs) {
       
        if (strs.length==0) return "";
        if (strs.length==1) return strs[0].substring(0);
        int min = Integer.MAX_VALUE;
        for (int i = 0;i<strs.length;i++) {
            if(strs[i].length()<min) {
                min=strs[i].length();
        }
    }
        int i = 0;
        for (;i<min;i++){
            if(!is_same(strs,i)) break;
        }
        return strs[0].substring(0,i);
    }
public boolean is_same(String[] strs,int i){
        int m=0;
        for(int j=0;j<strs.length-1;j++){
            if(strs[j].charAt(i)==strs[j+1].charAt(i)){
                m++;
            }else{
                return false;
            }
        }
        return true;
    }	
public static void main(String args[]) {
    		String[] s= {"flower","flow","flight"};
    		String ans=longestcommen(s);
    		System.out.println(ans);
    	}
    }

在这里插入图片描述

Python

class Solution(object):
    def longestCommonPrefix(self, strs):
        if len(strs)==0:
            return ""

        min = sys.maxint
        for i in range(len(strs)):
            if len(strs[i]) < min:
                min=len(strs[i])
        s=0
        for j in range(0,min):
            if(self.is_same(strs,j)):
                s+=1
            else:
                break
        return strs[0][0:s]

    def is_same(self,strs,i):
        m=0
        for k in range(len(strs)-1):
            if(strs[k][i]==strs[k+1][i]):
                m+=1
            else:
                return False
        return True
       

在这里插入图片描述

解法二 水平比较

在这里插入图片描述
我们将字符串水平排列,寻找第0 个和第 1 个字符串的最长子串,结果为 fl,再把结果和第 2 个字符串比较,结果为 fi,即为最终结果。

Java

 class Solution {
    public String longestCommonPrefix(String[] strs) {
        if (strs.length == 0) return "";
            String prefix = strs[0]; 
            for (int i = 1; i < strs.length; i++) {
                int minLen = Math.min(prefix.length(), strs[i].length());
                int j = 0;
                for (; j < minLen; j++) {
                    if (prefix.charAt(j) != strs[i].charAt(j)) {
                        break;
                    }
                }
                prefix = prefix.substring(0, j);
            }
            return prefix;
    }
}

在这里插入图片描述
时间复杂度:最坏情况和解法一是一样,n 个长度为 m 的完全相同的字符,就要比较所有的字符 S,S = n * m 。但对于正常情况,处于最短字符串前的字符串依旧要比较所有字符,而不是最短字符串个字符,相对于解法一较差。

空间复杂度:O(1)。

Python

class Solution(object):
    def longestCommonPrefix(self, strs):
        if len(strs)== 0:
            return ""
        prefix = strs[0]
        for i in range(1,len(strs)):
                minLen = min(len(prefix), len(strs[i]))
                count=0
                for j in range(0,minLen):
                    if (prefix[j] == strs[i][j]):
                        count+=1
                    else:
                        break
                prefix = prefix[0:count]
            
        return prefix

在这里插入图片描述

解法三 递归

我们把原来的数组分成两部分,求出左半部分的最长公共前缀,求出右半部分的最长公共前缀,然后求出的两个结果再求最长公共前缀,就是最后的结果了。

求左半部分的最长公共前缀,我们可以继续把它分成两部分,按照上边的思路接着求。然后一直分成两部分,递归下去。

直到该部分只有 1 个字符串,那么最长公共子串就是它本身了,直接返回就可以了。

Java

class Solution {
    public String longestCommonPrefix(String[] strs) {
        if (strs == null || strs.length == 0) return "";    
        return longestCommonPrefix(strs, 0 , strs.length - 1);
    }
    //递归不断分成两部分
    private String longestCommonPrefix(String[] strs, int l, int r) {
        if (l == r) {
            return strs[l];
        }
        else {
            int mid = (l + r)/2;
            String lcpLeft =   longestCommonPrefix(strs, l , mid);
            String lcpRight =  longestCommonPrefix(strs, mid + 1,r);
            return commonPrefix(lcpLeft, lcpRight);
        }
    }
//求两个结果的最长公共前缀
    String commonPrefix(String left,String right) {
        int min = Math.min(left.length(), right.length());       
        for (int i = 0; i < min; i++) {
            if ( left.charAt(i) != right.charAt(i) )
                return left.substring(0, i);
        }
        return left.substring(0, min);
    }
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

安替-AnTi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值