【leetcode】【初级算法】【字符串9】最长公共前缀

题目

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

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

示例 1:

输入:strs = [“flower”,“flow”,“flight”]
输出:“fl”
示例 2:

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

题解一:横向扫描

自己写的,是官方题解的方法一,前两个字符串先比较出最长公共前缀,再把公共前缀跟下一个比较。

java解

class Solution {
    public String longestCommonPrefix(String[] strs) {
        if(strs == null || strs.length ==0){
            return "";
        }
        // java中字符串的长度和数组的长度函数不同;
        int length = strs.length;
        String str1 = new String();
        String str2 = new String();
        str1 = strs[0];
        for(int i = 0;i<length-1;i++){
            StringBuilder sb = new StringBuilder();
            str2 = strs[i+1];
            int slength =0;
            if (str1.length()>str2.length()){
                slength = str2.length();                
            }
            else{
                slength = str1.length();
            }
            int pos = 0;
            while(pos<slength){
                if(str1.charAt(pos)==str2.charAt(pos)){
                    pos++;
                }else{
                    break;
                }
            }
            if(pos==0){
                return "";
            }
            for(int j=0;j<pos;j++){
                sb.append(str2.charAt(j));                
            }
            str1 = sb.toString();
        }
        return str1;
    }
}

官方题解中因为每次和公共前缀的比较 操作相同所以,将比价写为函数。
substring()
(1)substring是用来截取字符串的,根据参数的个数不同,方法含义也不同;
(2)substring(0,2)这个只含开头不含结尾,因此截取是截取两个字符,从第一个到第二个字符,不包含第三个。
(3)substring(2)这个表示截掉前两个,得到后边的新字符串。

class Solution {
    public String longestCommonPrefix(String[] strs) {
        // 如果字符串数组是空,或者长度为零,则最长公共前缀就返回""
        if(strs==null || strs.length==0){
            return "";
        }
        // 定义一个存放公共前缀的字符串
        String prefix = strs[0];
        // 定义一个存放字符串数组长度的变量 count
        int count = strs.length;
        // 遍历字符串数组中每一个字符串
        for(int i=1;i<count;i++){
            prefix = longestCommonPrefix(prefix,strs[i]);
            if(prefix.length()==0){
                break;
            }
        }
        return prefix;
        
    }
    // 比较两个字符串的最长公共前缀
    public String longestCommonPrefix(String str1,String str2){
        int length = Math.min(str1.length(), str2.length());
        int index = 0;
        while(index<length && str1.charAt(index)==str2.charAt(index)){
            index++;
        }
        return str1.substring(0,index);
    }
    
}

python解

class Solution:
    def longestCommonPrefix(self, strs: List[str]) -> str:
        # 方法一 横向扫描
        # 第一步 判空
        if not strs:
            return ""
        # 第二步 定义参数 存放公共前缀 存放数组长度
        prefix = strs[0]
        count = len(strs)
        # 第三步 遍历比价得到最长公共前缀
        for i in range(1,count):
            prefix = self.lcp(prefix,strs[i])
            # 返回的就是最长公共前缀了,再判断一下是否为空
            if not prefix:
                break
        return prefix
    
    def lcp(self, str1, str2):
        # 第一步 遍历前准备,只用遍历最短的字符就好 再定义一个索引
        length = min(len(str1),len(str2))
        index = 0
        # 遍历
        while index<length and str1[index]==str2[index]:
            index+=1
        return str1[:index]

题解二:纵向扫描

java解

遍历每个字符串的第一个元素是否都相等(j),再循环第二个元素。

class Solution {
    public String longestCommonPrefix(String[] strs) {
        // 第一步先判空 学习数组的判空方式
        if(strs==null || strs.length == 0){
            return "";
        }
        // 第二步定义需要的变量 存放第一个字符串的长度length
        int length = strs[0].length();
        // 定义存放字符串数组的长度变量 count
        int count = strs.length;
        // 遍历
        for(int i = 0 ;i<length;i++){
            // 当前比较第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];
    }
    
}

python解

class Solution:
    def longestCommonPrefix(self, strs: List[str]) -> str:
        # 方法二 纵向扫描
        # 第一步:判空
        if not strs:
            return ""
        # 第二步:遍历前准备工作,定义参数
        length = len(strs[0])
        count = len(strs)
        # 第三步:遍历
        for i in range(length):
            c = strs[0][i]
  #          if any(i==len(strs[j]) or strs[j][i]!=c for j in range(1,count)):
            for j in range(1,count):
                if i==len(strs[j]) or c!=strs[j][i]:
                    return strs[0][:i]
        return strs[0]

题解三:分治

Java解

class Solution {
    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());
        // 如果当前位置i的字符不想等 返回当前的最长公共前缀
        for(int i=0;i<minLength;i++){
            if(lcpLeft.charAt(i)!= lcpRight.charAt(i)){
                return lcpLeft.substring(0,i);
            }
        }
        // 循环完之后发现没有不想等的 就返回最短的这个字符串。
        return lcpLeft.substring(0,minLength);
    }
    
}

python解

class Solution:
    def longestCommonPrefix(self, strs: List[str]) -> str:
        # 方法三 分治
        # 第一步 定义一个函数处理从字符串开始statt到结尾end的函数
        def lcp(start, end):
            # 终止条件:处理start指针到end指针处理完为止
            if start == end:
                return strs[start]
            
            # 分治的思想就是不断的从中间分开 分成小问题处理
            mid = (start+end)//2
            lcpleft,lcpRight = lcp(start,mid),lcp(mid+1,end)
            # 只用比较较短的字符串长度就可
            minLength = min(len(lcpLeft),len(lcpRight))
            # 遍历 一旦不想等就返回当前长度即为最长公共前缀。
            for i in range(minLength):
                if lcpLeft[i] != lcpRight[i]:
                    return lcpLeft[:i]
                
            return lcpLeft[:minLength]
        return "" if not strs else lcp(0,len(strs)-1)
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值