Leetcode题库-最长公共前缀(java语言版)

题目描述:

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

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

示例 1:

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

示例 2:

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

说明:

所有输入只包含小写字母 a-z 。

这道题看题目描述和测试用例,会发现不是难题,就是一个字符串数组,求数组中的每个元素是否有公共的前缀,而且这个前缀必须的是最长。

但其实这道题很有深度,有好多种解法,什么二分查找,什么分治法等等。但我用的就是最直白的方法,两个for循环,理解起来也好理解,其他方法,我还在研究,本博客会不断补充,先将我的想法,思路和大家分享一下。

第一,要求最长的公共前缀,我想得现有一个字符串数组

第二,从数组中的第一个元素开始比较,将第一个元素的每一个字符和第二个元素,第三个。。。第i个元素的每一个字符进行比较,如果相同就建立一个字符串变量将相同的字符加起来,组成一个字符串(可能有点绕口,例如,【"flow","flower","flo"】,将flow中的每一个字符和其余的元素比较,f与第二第三相同,付给变量,l和第二第三元素的字符相同付给变量,等等最后,输出的变量就是flo),最后通过判断,输出

扫描二维码关注公众号,回复: 9557575 查看本文章

          注:这个用到了变量存储相同字符,有好多种思路,

一用字符串str+=相同字符,

二,用stringbulider来append增加字符。

三,这个不是用来存储相同字符的方式,这种方式反其道而行之,用到了substring方法,就是字符串截取方法,当判断没有元素相同时,就输出第一个字符(因为是将第一个字符和其他元素字符比较)从下标为0,到没有相同元素的下标之间的字符就是相同字符,能比存储字符串简单一点,存储字符串比这个能好理解点。好了,说了这么多绕口的话,我们来看代码。因为容易理解。

代码如下: 

 public static void main(String[] args){
          String  []strs = {"flower","ulow","plight"};
          最长公共前缀 zz = new 最长公共前缀 ();
          System.out.println(zz.longestCommonPrefix ( strs ));


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

        for (int i = 0; i < strs[0].length() ; i++){
            char c = strs[0].charAt(i);
            for (int j = 1; j < strs.length; j ++) {
//                两种情况第一种,前缀等于数组元素的长度,flowower---flow(前缀的长度最大就是数组中长度最小的那个元素。)
//                第二种 从第一个字符开始,不相等时,就证明找到了,不相等字符之前的字符都是相等的。
                if (i == strs[j].length() || strs[j].charAt(i) != c){
                    return (strs[0].substring(0, i)) ;
                }

            }
        }
        return null;
    }
}

这个使用到了substring,也好理解,找到不相同的那个字符对应的下标,输出0-这个不相同字符下标的字符串就是要求的最长公共前缀

还有一种用stringbuilder的,效果一样,判断也一样,更好理解,相同就添加,不相同就输出,

代码如下:

用subtrings方法,要么用StringBuilder来作为每个字符的连接,当相等时,将相等字符,
添加到StringBUilde中,不相等,或者前缀长度等于小于i时,证明已经找到最大前缀了,输出sb。
//j == strs.length - 1意思是,如果第一个元素的字符与后面元素的字符相等时,
那么最后那一个元素的字符也相等于第一个元素的字符。就如同flot,flo,floa.f与后面两个相同,
如果一相等就保存的话,那么,就会重复,fflloo,但如果相同时,且j是最后一个元素下标时
(总元素个数减去第一个元素),那么这样添加就不会重复了,
f直等到一直重复到最后一个元素,然后就增加一次,这样不管数组中有多少个元素,这样的话就只保存相同的一次。
    StringBuilder sb = new StringBuilder();
         if (strs[j].length()==i ||strs[j].charAt(i) != c) {
         return sb.toString();
        }
         if (strs[j].charAt(i) == c && j == strs.length - 1){
          sb.append ( c );

代码中的注释就不用细看了,代码没多少东西,这种方法比较容易想到,简单粗暴。时间复杂度O(n),n为所有字符的数量。

但是没有其他方法好,而且不那么高大上,本人能力有限,只能想到这种,等学会答案中那几种方法了,会补充到后面。

执行结果:

 

程序用时:

     第二种方法,比第一种简便更好理解,执行速度更快。这种方法让数组中的第一个元素成为前缀,然后循环字符串数组,判断数组中的每一个元素是否以声明的那个前缀一样,一样就不动,不一样就将声明的那个前缀从0-长度减一,循环知道找到每一个元素都开头的那个前缀。用到了字符串startswith方法和substring方法。

这种方法简便执行速度快,,代码更让加简便,用到了startsWith这个方法,
判断数组中的每一个元素是否以prefix开头,不是的话,让prefix-1,
在判断是否与数组中的元素相同.
    public String longestCommonPrefix(String[] strs) {
           String prefix=strs[0];
           for (int i = 0;i<strs.length;i++){
                while (!strs[i].startsWith ( prefix )){
                    prefix = prefix.substring ( 0,prefix.length ()-1 );
                    if (prefix.isEmpty()) return "";
                }
           }
           return prefix;
    }

执行用时:

总结:这道题看似简单,实际有很多需要想的地方,本人能力有限,想法不够只能想到这种方法,看到答案中许多优质的解答一时间觉得自己想问题太浅显了。其他方法还在慢慢消化,本博客会慢慢补充。

2019-1-19记录

发布了43 篇原创文章 · 获赞 6 · 访问量 6689

猜你喜欢

转载自blog.csdn.net/weixin_37850160/article/details/86556879