字符串数组的最长公共前缀的三种求解思路及JAVA代码

package day07;
//找出字符串数组的最长公共前缀
//如果不存在公共前缀,返回空字符串 ""。
public class LongestCommonPrefix {
    public static void main(String[] args) {
        String[] strs = {"flower","flow", "flight"};
        //测试思路1
        //String res = longestCommonPrefix(strs);

        //测试思路2
        //String res = longestCommonPrefix02(strs);

        //测试思路3
        String res = longestCommonPrefix02(strs);
        System.out.println(res);

    }

    //思路1:遍历字符串数组,先找出前两个的最长公共前缀,再以这个前缀和第三个字符串匹配找出他们的最长公共前缀,以此类推-->横向比较
    public static String longestCommonPrefix(String[] strs) {
        if (strs == null || strs.length == 0) {
            return new String("");
        }
        if (strs.length == 1) {
            return strs[0];
        }

        int length = strs.length;
        String prefix = strs[0];//默认最长公共前缀为第一个字符串
        for(int i  = 1; i < length; i ++) {
            prefix = longestCommonPrefix(prefix, strs[i]);//每次都以上一次得到的最长公共前缀和下一个字符串匹配
            //如果当前最长公共前缀为 "" 则没有必要再进行
            if ( prefix.length() == 0 ) {
                break;
            }
        }

        return prefix;
    }

    //前缀,重载
    public static String longestCommonPrefix(String str1, String str2) {
        int length = Math.min(str1.length(), str2.length());
        int index = 0;
        while (index < length && str1.charAt(index) == str2.charAt(index)) {
            index ++;
        }

        //返回两个字符串的最长公共前缀
        return str1.substring(0,index);
    }

    //思路2:纵向比较,从第0列开始比较每一个字符串的相同列字符是否相等
    public static String longestCommonPrefix02(String[] strs) {
        if (strs == null || strs.length == 0) {
            return new String("");
        }
        if (strs.length == 1) {
            return strs[0];
        }

        int cols = strs[0].length();
        int length = strs.length;

        for(int i = 0; i < cols; i ++) {
            char c = strs[0].charAt(i);//第 i 列
            for(int j = 1; j < length; j ++) {//比较每一个字符串的每一列
                //如果已经匹配到一个字符串的末尾或者有一个不相等,就得到了最长公共前缀
                if (i == strs[j].length() || c != strs[j].charAt(i)) {
                    return strs[0].substring(0,i);
                }
            }
        }

        //进行到这里,说明strs[0] 是后面的所有字符串的前缀
        return strs[0];
    }

    //思路3:分治法,根据思路1的思想,满足交换律
    public static String longestCommonPrefix03(String[] strs) {
        if (strs == null || strs.length == 0) {
            return new String("");
        }
        if (strs.length == 1) {
            return strs[0];
        }

        return longestCommonPrefix03(strs,0,strs.length - 1);

    }

    public static String longestCommonPrefix03(String[] strs, int start, int end) {
        if (start == end) {//不能再分
            return strs[start];
        } else {
            int mid = (start + end) / 2;
            String lcpLeft = longestCommonPrefix03(strs,start,mid);
            String lcpRight = longestCommonPrefix03(strs,mid + 1, end);
            return commonPrefix(lcpLeft,lcpRight);
        }
    }

    public static String commonPrefix(String str1, String str2) {
        int minLength = Math.min(str1.length(), str2.length());
        for(int i = 0; i < minLength; i ++) {
            if (str1.charAt(i) != str2.charAt(i)) {
                return str1.substring(0,i);
            }
        }

        return str1.substring(0,minLength);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值