Leetcode No.14-最长公共前缀(简单)——Java/Python

难度:中等

编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 “”。
示例:
输入: [“flower”,“flow”,“flight”]
输出: “fl”

方法一:(暴力法/水平扫描法)

看到这个题之后,我的第一想法是直接进行比较,也就是暴力法,但是数组中字符串的长度不定,肯定不可能写尽循环,于是我想到了“1和2比,得到公共前缀存起来,然后再用1和2的公共前缀和3比……以此类推,当result为空的时候,就直接停止循环,并返回result(最开始的时候,我没有做判result为空这一步,是看了官方题解之后加的)”。

图 1. 查找最长公共前缀 (水平扫描法)

class Solution {
    public String twoStringfindSame(String str1,String str2){
        int minLen = str1.length()<str2.length()?str1.length():str2.length();
        String result = "";
        for(int i = 0;i<minLen;i++){
            if(str1.charAt(i)!=str2.charAt(i))
                break;
            else
                result += str1.charAt(i);
        }
        return result;
    }
    
    public String longestCommonPrefix(String[] strs) {
        int len = strs.length;
        if(strs.length==0 || strs==null){
            return "";
        }
        String result = strs[0];
        for(int i=1;i<len;i++){
            if(result=="")
        		return "";
            else
                result = twoStringfindSame(result,strs[i]);
        }
        return result;
    } 
}


这种简单粗暴的方式……果然,时间和空间方面效率都太差了。像个憨憨。


然后看了官方题解之后我发现,我这个思路是和官方题解的方法一——水平扫描法思路(其实就是暴力法)一致,可是官方题解的代码非常精妙……!!
官方的这个暴力解法,可以称之为最棒的暴力解法

class Solution {
	public String longestCommonPrefix(String[] strs) {
		if (strs.length == 0) 
			return "";
		String prefix = strs[0];
		for (int i = 1; i < strs.length; i++){
	  		while (strs[i].indexOf(prefix) != 0) {
	  			//不等于0,就说明是-1,没有从头就找到对应的子串,
	  			//于是使用substring函数,将prefix串减掉最后一个字符
	      		prefix = prefix.substring(0, prefix.length() - 1);
	      		if (prefix.isEmpty()) 
	      			return "";
	  		}  
		}      
		return prefix;
	}
}
作者:LeetCode
链接:https://leetcode-cn.com/problems/longest-common-prefix/solution/zui-chang-gong-gong-qian-zhui-by-leetcode/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


时间方面提高了很多。同样都是暴力解法,人与人差别太大了。

知识盲点:
  • indexof()方法:
    官方题解最大的亮点就是妙用了该方法。

indexOf() 方法有以下四种形式:

  1. public int indexOf(int ch): 返回指定字符在字符串中第一次出现处的索引,如果此字符串中没有这样的字符,则返回 -1。
  2. public int indexOf(int ch, int fromIndex): 返回从 fromIndex 位置开始查找指定字符在字符串中第一次出现处的索引,如果此字符串中没有这样的字符,则返回 -1。
  3. int indexOf(String str): 返回指定字符在字符串中第一次出现处的索引,如果此字符串中没有这样的字符,则返回 -1。 ★ ★
  4. int indexOf(String str, int fromIndex): 返回从 fromIndex 位置开始查找指定字符在字符串中第一次出现处的索引,如果此字符串中没有这样的字符,则返回 -1。

官方题解中的使用,使用的是第三种形式


看到另一位精选题解,思想相同,但这个代码更通俗易懂。效果也很不错。

class Solution {
    public String longestCommonPrefix(String[] strs) {
        if(strs.length == 0) 
            return "";
        String ans = strs[0];
        for(int i =1;i<strs.length;i++) {
            int j=0;
            //原答主用的是for循环,我觉得while看着顺眼并想和官方题解做一个对比。
            //for(;j<ans.length() && j < strs[i].length();j++)
            while(j<ans.length() && j < strs[i].length()){
                if(ans.charAt(j) != strs[i].charAt(j)){
                    break;
                }
                j++;
            }
            ans = ans.substring(0, j);
            if(ans.equals(""))
                return ans;
        }
        return ans;
    }
}
作者:guanpengchn
链接:https://leetcode-cn.com/problems/longest-common-prefix/solution/hua-jie-suan-fa-14-zui-chang-gong-gong-qian-zhui-b/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

在这里插入图片描述

复杂度分析:
  • 时间复杂度 O ( S ) O(S) O(S) S S S是所有字符串中字符数量的总和。
    最坏的情况下, n n n个字符串都是相同的。算法会将 S 1 S1 S1与其他字符串 [ S 2 … S n ] [S_2…S_n] [S2Sn]都做一次比较。这样就会进行 S S S次字符比较,其中 S S S是输入数据中所有字符数量。

  • 空间复杂度 O ( 1 ) O(1) O(1),我们只需要使用常数级别的额外空间。

附:水平扫描法的Python解答
  • 知识扩充:
  • Python中的find()方法检测字符串中是否包含子字符串s 。
  • 如果包含子字符串返回开始的索引值,否则返回-1。
  • 如果指定 beg(开始) 和 end(结束) 范围,则检查是否包含在指定范围内
  • 语法:str.find(str, beg=0, end=len(string))
    • str – 指定检索的字符串
    • beg – 开始索引,默认为0。
    • end – 结束索引,默认为字符串的长度。
class Solution:
    def longestCommonPrefix(self, strs: List[str]) -> str:
        if len(strs) == 0:
            return ''
        s = strs[0]
        for i in range(1, len(strs)):
            while strs[i].find(s) != 0 :
                s = s[:-1]   #列表切片,每次长度减一
        return s

作者:huamei
链接:https://leetcode-cn.com/problems/longest-common-prefix/solution/python-shui-ping-sao-miao-fa-by-huamei/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

方法二:(纵向扫描法)

方法三:(分治法)

方法四:(二分查找法)

方法二三四均来自官方题解,附上链接
https://leetcode-cn.com/problems/longest-common-prefix/solution/zui-chang-gong-gong-qian-zhui-by-leetcode/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值