LeetBook乐扣题库 14. 最长公共前缀

一 题目描述

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

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

示例 1:

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

示例 2:

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

二 方法代码

  • 方法一

public String longestCommonPrefix(String[] strs) {
        if(strs == null || strs.length == 0) {
            return "";
        }

        String prefix = strs[0];
        int len,index;
        //比较第一个和第二个字符串的公共前缀,然后拿着结果再和第三个比较,再和第四个比较...
        for(int i = 1; i < strs.length; i++) {
            len = Math.min(prefix.length(), strs[i].length());
            //(prefix.length() > strs[i].length()) ? strs[i].length() : prefix.length();
            index = 0;
            //len代表两个字符串中最短的长度,这样避免溢出
            //index表示从第一个字符开始比较两个字符串中有多少位字符一样
            //得到两个字符串中最长前缀的位数,然后最后统一取出
            while(index < len && prefix.charAt(index) == strs[i].charAt(index)) {
                index++;
            }
            prefix = prefix.substring(0, index);
            if(prefix.isEmpty()) {
                break;
            }
        }
        return prefix;
    }
  • 方法二

public String longestCommonPrefix1(String[] strs) {
        if (strs == null || strs.length == 0) {
            return "";
        }

        //求字符串数组中最短的字符串长度
        int minLength = strs[0].length();
        for(String str : strs) {
            if(str.length() < minLength) {
                minLength = str.length();
            }
        }

        int index = 0;
        //按列比较每个字符串的字符是否一致
        while(index < minLength) {
            //flag表示if语句执行,即出现了字符不一致的情况,跳出while
            boolean flag = true;
            for(int i = 0; i < strs.length - 1; i++) {
                if(strs[i].charAt(index) != strs[i + 1].charAt(index)) {
                    flag = false;
                    break;
                }
            }
            if(!flag) {
                break;
            }
            index++;
        }
        return strs[0].substring(0, index);
    }
  • 方法三

这个方法力扣官方说叫分治,就是把问题分为更小的子问题解决,其实我更愿意叫它递归,他的原理如图:

public String longestCommonPrefix2(String[] strs) {
        if(strs == null || strs.length == 0) {
            return "";
        }else{
            return function(strs, 0, strs.length - 1);
        }
    }

    public String function(String[] strs, int start, int end) {
        if(start == end){
            //这种情况说明只有一个字符串了,就返回这个字符串给上一级
            //返回之后和另一半返回的同样只剩下一个的字符串比较公共前缀,然后再返回给上一级
            return strs[start];
        }else{
            //这种情况说明还可以分开两半,就继续分,直到分到不能分,然后挨个返回
            int mid = start + (end - start)/2;
            String left = function(strs, start, mid);
            String right = function(strs, mid + 1, end);
            return getPrefix(left,right);
        }
    }

    public String getPrefix(String left, String right) {
        int minLength = Math.min(left.length(), right.length());
        for (int i = 0; i < minLength; i++) {
            if (left.charAt(i) != right.charAt(i)) {
                return left.substring(0, i);
            }
        }
        return left.substring(0, minLength);
    }
  • 方法四

public String longestCommonPrefix3(String[] strs){
        //很巧妙的方法,字符串排序,比较第一个和最后一个的公共前缀
        //但是不建议一解题就排序,排序的时间复杂度会比较高
        Arrays.sort(strs);
        String prefix = "";
        //遍历第一个和最后一个字符串的每一个字符,
        //并且i不能超过两个字符串中较短字符串的长度,否则会溢出
        for(int i = 0; i < strs[0].length() && i < strs[strs.length-1].length(); i++){
            if(strs[0].charAt(i) == strs[strs.length-1].charAt(i)){
                prefix = prefix + strs[0].charAt(i);
            }else {
                break;
            }
        }
        return prefix;
    }

三 性能分析和比较

方法一和二都是:

时间复杂度:O(S),其中S是所有字符串中字符数量的总和。在最坏情况下,需要比较每个字符。

方法三是:

复杂度也是O(S),但由于其使用了分治法,通过将问题分成较小的子问题来解决,每次递归调用的字符串数量减半,每次只比较两个字符串的公共前缀,减少了不必要的比较次数。相比之下,方法一需要每次比较所有字符串,效率较低。分治法更快的原因主要在于其减少了不必要的比较次数,

方法四是:

排序太慢了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值