LeetCode解题-#14-Longest Common Prefix

题目描述:
找出一组字符串中的最长共同前缀。

分析:
例如 abc, abd, ab,它们的最长共同前缀是 ab。

思路:
学习过的 Trie 刚好能解决这个问题,虽然不会是最优解,但可以练练手。
Trie:http://blog.csdn.net/cuit/article/details/78495561

先定义好 Trie 树 的数据结构:
这里用 HashMap(C#中是 Dictionary)存储树的子结点,优点是不用存储多余的空数组元素。
只实现了一个 Add(string s) 方法,用于添加字符串。

    public class Trie
    {
        public TrieNode Root;
        public Trie()
        {
            Root = new TrieNode();
        }
        public void Add(string s)
        {
            TrieNode runNode = Root;
            for (int i = 0; i < s.Length; i++)
            {
                var children = runNode.Children;
                char c = s[i];
                TrieNode next = null;
                if (children.TryGetValue(c, out next))
                {
                    next = children[c];
                }
                if (next == null)
                {
                    children.Add(c, new TrieNode());
                }
                runNode = children[c];
            }
            runNode.IsEnd = true;
        }      
    }
    public class TrieNode
    {
        public bool IsEnd { get; set; }
        public Dictionary<char,TrieNode> Children { get; set; }

        public TrieNode()
        {
            Children = new Dictionary<char, TrieNode>();
            IsEnd = false;
        }
    }

然后依次把字符串数组插入Trie中,然后只要找到子结点的数量等于 1 且还有子结点时,即表示这些字符串还在共同前缀的树枝中,反正即表示有分支了,也即这些字符串不再有共同前缀了。

    public string LongestCommonPrefix(string[] strs) {
        if(strs.Length == 0)
        {
            return "";
        }
        Trie t = new Trie();
        for(int i = 0; i < strs.Length; i++)
        {
            t.Add(strs[i]);
        }
        StringBuilder sb = new StringBuilder();
        TrieNode runNode = t.Root;
        while (runNode.Children.Count == 1 && !runNode.IsEnd)
        {
            var keys = runNode.Children.Keys;
            foreach(var k in keys)
            {
                sb.Append(k);
                runNode = runNode.Children[k];
            }
        }
       return sb.ToString();
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值