LeetCode--14. Longest Common Prefix

题目链接:https://leetcode.com/problems/longest-common-prefix/

这是一个easy的题目,但是涉及的思维方式和方法还有一些用的比较少的高级数据结构都是值得讨论研究的,意味深长。LeetCode的前两百道题目各个都是经典,引人思考。这个题目要求一个字符串集合的最长公共前缀。

思路一:

一拿到题目的思路有两个,其中一个是Trie树,第二个就是这个实现起来相对快一些:最长公共前缀长度n一定小于等于最短字符串,然后逐个比较个字符串中第i个(i<=n)字符是否相同即可,于是有了如下代码:

class Solution {
    public String longestCommonPrefix(String[] strs) {
        if(strs.length==0 || strs==null)
            return "";
        
        StringBuilder sb=new StringBuilder();
        int minLength=Integer.MAX_VALUE;
        
        for(int i=0;i<strs.length;i++)
            minLength=Math.min(minLength,strs[i].length());
        
        for(int j=0;j<minLength;j++)
        {
            char c =strs[0].charAt(j);
            int k=1;
            for(;k<strs.length;k++)
                if(c!=strs[k].charAt(j))
                    break;
            if(k<strs.length)
                break;
            sb.append(c);
        }
        return sb.toString();
    }
}

最坏时间复杂度为O(mn),空间复杂度为O(1),性能一般。

思路二:

先比较前两个字符串得到最长公共前缀,再用的到的最长公共前缀与后面的字符串一一比较,从而得到最终的最长公共前缀

代码很简单,但是我觉得Solutions里面的解法更优雅直接:

public String longestCommonPrefix1(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)
            {
                prefix = prefix.substring(0, prefix.length() - 1);
                if (prefix.isEmpty()) return "";
            }
        }
        return prefix;
    }

思路三:

上述两两比较的方式(一趟复杂度为O(n))可以用归并的思想进行优化(一趟复杂度为logn),归并思想可以参考这两篇:https://blog.csdn.net/To_be_to_thought/article/details/83994248https://blog.csdn.net/To_be_to_thought/article/details/83988767

代码如下:

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

    private String longestCommonPrefix(String[] strs, int l, int r) {
        if (l == r) {
            return strs[l];
        }
        else {
            int mid = (l + r)/2;
            String lcpLeft =   longestCommonPrefix(strs, l , mid);
            String lcpRight =  longestCommonPrefix(strs, mid + 1,r);
            return commonPrefix(lcpLeft, lcpRight);
        }
    }

    String commonPrefix(String left,String right) {
        int min = Math.min(left.length(), right.length());
        for (int i = 0; i < min; i++) {
            if ( left.charAt(i) != right.charAt(i) )
                return left.substring(0, i);
        }
        return left.substring(0, min);
    }

思路四:

前缀树这个思路是比较自然的思路,因为Trie树就是为这个而设计的数据结构。将字符串集合里的字符串建立在Trie树上,然后数从根节点到第一个分叉节点经历的边数。未完待续!!!

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值