力扣解题思路:14. 最长公共前缀 纠错记录

14. 最长公共前缀


思路:编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀,返回空字符串 “”。

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

我首先想到的就是先取第一个字符串作为基准,然后再创建一个整数数组(长度和第一个字符串一样长),然后用其他几个字符串和他相比较(相同的字符则在对应位置加1),后来一想发现不仅太麻烦,而且逻辑不严密。->
实际上我们并不需要一个额外的数组,直接将其他的字符串和第一个字符串相比较接可以了,怎么比较呢?不断地判断第二个字符串的前缀是不是第一个字符串的前缀,但是为了找到最大的前缀,我们应该从第二个字符串的最长长度开始比较(不符合再不断地缩小长度直到满足)
->
那我们如何判断该前缀是否存在呢?indexOf()这个方法派上了用场,只要该结果返回0,证明该字符串就是前缀(因为从0开始匹配了)。
完整代码如下:

public String longestCommonPrefix(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) {//等于0就是存在公共部分
            prefix = prefix.substring(0, prefix.length() - 1);//每次长度减少并判断是否是公共部分
            if (prefix.isEmpty()) return "";//直到减少到字符串为空还没有公共就返回空
        }        
    return prefix;
}

还有就是使用前缀树,用count记录经过此路径的单词数量:

class Solution {
    public String longestCommonPrefix(String[] strs) {
        if(strs.length == 0) return "";
        if(strs.length == 1) return strs[0];
        Tire tire = new Tire();
        for (String str : strs) {
            if (str.length() == 0) {
                return "";
            }
            tire.insert(str);
        }
        return tire.searchMaxPrefix(strs[0],strs.length);
    }
    class Tire {
        class TireNode {
            TireNode[] child;
            boolean flag;
            int count;
            public TireNode() {
                child = new TireNode[26];
                flag = false;
                count = 0;
            }
        }
        /** 前缀树的根节点 */
        TireNode root;
        public Tire() {
            root = new TireNode();
        }
        /**
         * 插入每一个单词进入前缀树
         * @param str
         */
        public void insert(String str) {
            TireNode cur = root;
            cur.count++;
            for (int i = 0; i < str.length(); i++) {
                if (cur.child[str.charAt(i) - 'a'] == null) {
                    cur.child[str.charAt(i) - 'a'] = new TireNode();
                }
                cur = cur.child[str.charAt(i) - 'a'];
                cur.count++;
            }
            cur.flag = true;
        }
        /**
         * 查找最长公共前缀
         * @return
         */
        public String searchMaxPrefix(String s,int len) {
            StringBuilder sb = new StringBuilder();
            TireNode cur = root;
            for(int i = 0;i < s.length(); i++){
                //if(cur.count < len) break;
                if (cur.child[s.charAt(i) - 'a'].count == len) {
                    sb.append(s.charAt(i));
                    cur = cur.child[s.charAt(i) - 'a'];
                }else{
                    return sb.toString();
                }
            }
            return sb.toString();
        }
    }
}

不知道为啥,写的时候老是忘记cur = cur.child[s.charAt(i) - ‘a’];这句,下不为例!!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值