Leetcode刷题(十九)

最长公共前缀(Easy)

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

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

示例 1:

输入:strs = ["flower","flow","flight"]
输出:"fl"
示例 2:

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

1 <= strs.length <= 200
0 <= strs[i].length <= 200
strs[i] 仅由小写英文字母组成
Related Topics
字典树
字符串

思路分析

这道题提示同显示需要用到字典树这个数据结构,那么什么是字典树呢?

字典树是一种用于存储字符串的树形数据结构,其中每个节点代表一个字符。这种结构在处理大量字符串,尤其是在自动补全和拼写检查等应用中非常有用。主要思想是利用字符串的公共前缀来节约存储空间。很好地利用了串的公共前缀,节约了存储空间。
Leetcode刷题(十九)_第1张图片
当然也可以使用二维数组的形式来存储字典树。那也就是说,数组本身的索引分别代表26个字母,索引所指位置存储的值代表了子数组所在位置。
Leetcode刷题(十九)_第2张图片
由字典树的性质可以知道,这道题中,要想字符串拥有最长公共前缀,那么说明我们要找到子节点数量为1的最长的路径。

代码实现

//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
    public String longestCommonPrefix(String[] strs) {
        Trie trie = new Trie();
        if (strs.length == 0) return "";
        for (String str : strs) {
            trie.insert(str);
        }
        StringBuilder prefix = new StringBuilder();
        TrieNode current = trie.getRoot();
        while (countChildren(current) == 1 && !current.isEndOfWord) {
            for (int i = 0; i < current.children.length; i++) {
                if (current.children[i] != null) {
                    prefix.append((char) (i + 'a'));
                    current = current.children[i];
                    break;
                }
            }
        }
        return prefix.toString();

    }

    //计算子节点数量
    private int countChildren(TrieNode node) {
        int count = 0;
        for (int i = 0; i < node.children.length; i++) {
            if (node.children[i] != null) {
                count++;
            }
        }
        return count;
    }

    //定义字典树的节点
    class TrieNode {
        private TrieNode[] children;
        private boolean isEndOfWord;

        public TrieNode() {
            children = new TrieNode[26]; // 假设只有26个英文字母
            isEndOfWord = false;
        }

        //插入操作
        public void insert(String word) {
            TrieNode current = this;
            for (char c : word.toCharArray()) {
                int index = c - 'a';
                if (current.children[index] == null) {
                    current.children[index] = new TrieNode();
                }
                current = current.children[index];
            }
            current.isEndOfWord = true;
        }

    }

    //定义字典树
    public class Trie {
        private TrieNode root;

        public Trie() {
            root = new TrieNode();
        }

        public TrieNode getRoot() {
            return root;
        }

        public void insert(String word) {
            root.insert(word);
        }

    }

}

//leetcode submit region end(Prohibit modification and deletion)

其他方法

在我看了别人的方法后发现,java中自带一个方法String.startsWith(String s)来判断是否含有该前缀。并且我在查看这个函数时发现,这个函数的实现方法使用的也是字典树这个数据结构,所以我们可以把这个代码进行简化。

代码实现

class Solution {
    public String longestCommonPrefix(String[] strs) {
        if(strs.length == 0 )     //空则返回“”
            return "";
        String s = strs[0];       //初始前缀
        for(String str :strs)
        {
            while(!str.startsWith(s))   //判断是否含有该前缀
            {
                if(s.length()==0)
                    return "";
                s = s.substring(0,s.length()-1);//前缀长度-1
            }
        }
            return s;
    }
}


你可能感兴趣的:(Leetcode刷题实录,leetcode,算法)