题解 | NC55 #最长公共前缀#

最长公共前缀

http://www.nowcoder.com/practice/28eb3175488f4434a4a6207f6f484f47

题目描述

给你一个大小为n的字符串数组strs,其中包含n个字符串,编写一个函数来查找字符串数组中的最长公共前缀,返回这个公共前缀。

数据范围:0<=n<=5000, 0<=len(strs[i])<=5000

例1
输入:["abca","abc","abca","abc","abcc"]
返回值:"abc"

题目分析

想要获取数组中所有字符串的最长公共前缀,需要遍历每个字符串的字符,进行比较,比较的方法主要有两种:
①横向比较:先比较两个字符串的最长前缀,后面用前面得到的前缀不断与后面进行比较,得到最终的结果。
②纵向比较:可以对每个字符串的第一个、第二个...字符依次比较,直到有一个字符串不满足与其他字符串相同的条件就可以将前面累计的字符结果返回。

解题思路

方法1:横向比较

横向比较的过程比较简单,主要是对两个字符串的最长前缀进行比较,从第一个和第二个的比较结果,一直到最后一个字符串,比较过程如下: alt

alt

因为横向比较会重复比较前面比较过了的前缀部分,所以时间花费上相比纵向比较会更多。

方法2:纵向比较

纵向比较,需要一个记录结果的字符对象,对所有的字符串前缀依次进行比较,所有字符串都满足的字符记录到字符对象中,只要有一个不符合就可以直接返回对象结果,这里面主要是处理对何时返回对象结果的判断:
①当判断的字符到达某个字符串的尾部时,返回;
②当判断的字符不符合某个字符串的前缀时,返回;
③只有所有的字符串的前缀比较都通过后,才会将结果记录下来。

代码实现

方法1:横向比较

import java.util.*;

public class Solution {
    /**
     * 
     * @param strs string字符串一维数组 
     * @return string字符串
     */
    public String longestCommonPrefix (String[] strs) {
        if(strs == null || strs.length == 0) return "";
        if(strs.length == 1) return strs[0];
        // 横向比较字符串的最长前缀
        // 先获取第一个和第二个字符创最长公共前缀
        String same = getSimilar(strs[0], strs[1]);
        for(int i=2;i<strs.length;i++){
            // 将前面的最长公共前缀和后面的字符串进行求前缀
            same = getSimilar(same, strs[i]);
        }
        return same.toString();
    }
    
    public String getSimilar(String s1, String s2){
        String res = "";
        // 两个字符串求最长前缀的过程,从头开始比较判断
        for(int i=0; i<s1.length() && i<s2.length(); i++){
            if(s1.charAt(i) == s2.charAt(i)){
                res += s1.charAt(i);
            }else{
                break;
            }
        }
        return res;
    }
}

时间复杂度:O(nm)O(nm)O(nm),n是字符串数组长度,nm是字符串数组中所有的字符的数量,横向比较的过程最差需要遍历所有的字符,所以时间复杂度为O(nm)O(nm)O(nm)

空间复杂度:O(1)O(1)O(1),只需要常数级别变量。

方法2:纵向比较

import java.util.*;


public class Solution {
    /**
     * 
     * @param strs string字符串一维数组 
     * @return string字符串
     */
    public String longestCommonPrefix (String[] strs) {
        // write code here
        if(strs == null || strs.length == 0) return "";
        if(strs.length == 1) return strs[0];
        // 存储最长前缀
        StringBuilder res = new StringBuilder("");
        boolean flag = true;
        int index = 0;
        char test = ' ';
        while(flag){
            // 对数组中的字符串进行纵向判断
            for(int i=0;i<strs.length;i++){
                String str = strs[i];
                // 对第index个字符进行判断
                // 对于第一个字符串,未到字符串尾部,设置判断字符为index位上的
                if(i == 0 && index < str.length()){
                    test = str.charAt(index);
                }
                // 对于后面的字符串,需要判断是否与判断字符相同
                if(i > 0 && index <str.length() && str.charAt(index) != test){
                    flag = false;
                    break;
                }
                // 中间长度不够的直接返回
                if(test != ' ' && index >= str.length()){
                    flag = false;
                    break;
                }
                // 当前面的字符串都判断完了,就可以加入结果中
                if(i == strs.length-1){
                    if(test != ' ' && index < str.length()){
                        res.append(test);
                    }else{
                        flag = false;
                        break;
                    }
                }
            }
            index++;
        }
        return res.toString();
    }
}

时间复杂度:O(nm)O(nm)O(nm),n是字符串数组长度,nm是字符串数组中所有的字符的数量,纵向比较的过程最差需要遍历所有的字符,所以时间复杂度为O(nm)O(nm)O(nm)

空间复杂度:O(1)O(1)O(1),只需要常数级别变量。

全部评论

相关推荐

一共一个小时,面试难度以及自己的回答算是最近的面试压力比较大的,实习问了30分钟,中间穿插八股。1.redis数据结构2.redis持久化机制3.mysql索引底层4.聚簇索引与非聚簇索引5.索引优化6.索引失效7.mysql执行一条sql8.那么多索引mysql怎么选(不会)9.tcp与udp区别10.tcp为什么可靠11.消息队列作用12.kafka怎么保证消息有序性13.mcp是什么?14.skills是什么?15.jvm内存分配与回收过程(我讲了从创建对象到判断垃圾对象到垃圾回收我全说了一遍,是这个吗?)16.fullgc触发机制17.tcp的拥塞控制流程(不会了)18.分布式事务解决方案,说了2pc,3pc,tcc。算法是反转双向链表,没有按格式输出,但是面试官没让继续写了,面完以为挂了,结果晚上秒过,看看复试什么情况吧。今天百度打电话准备发offer了,业务跟在手子的差不多,很垂,并且说不分日常暑期,只看表现,会有转正机会,但是考虑再三还是拒绝了,百度实习薪资确实有点低,title也不如之前了,但是面试的二位业务老师我很喜欢,对我的评价也不错,希望之后能有机会共事。从三月份到现在一共面了六家,面试次数总共是8场,情况如下:脉脉二面(无答复,默认挂)百度二面已oc美团一面过,下周一二面shein一面过直接HR面游族一面过直接HR面腾讯一面过等待约二面滴滴明天一面面试通过率还是蛮高的,但是大部分都是日常,感觉对我现在的加成不大,大概率不会去,不知道暑期会是什么情况呢唉,希望能有面试吧,继续加油。字节被无hc直接取消了,现在还没人捞,有没有字节HR救救我
不管什么都不想跳动了:本人美团百度快手都待过,建议肯定是直接留快手多一点产出后转正or直接冲字节腾讯暑期吧。一是快手从福利到基建都吊打另外两家。美团现在这个业务比较惨,本来毛利就很低,亏损严重,今年很可能要优化人力降低成本,去了别说日常,就算暑期后面都很可能被优化。百度其实实习生权限挺高的,可以接触到一些含金量高的项目,但是现在的风评不如之前了,薪资也不高。二是转正概率和薪资是跟产出挂钩的,你都在手子已经积累产出了,去其他家日常实习产出都是从0开始,肯定不可能有你在手子转正可能性大啊,现在日常压根没必要去,而且我有两个师弟都是在快手日常转正的,不用太担心,安心留在手子一边多做一点产出然后一边冲字节腾讯暑期,字节腾讯今年实习岗位非常多的,不如好好把握这个,加油。
查看18道真题和解析
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务