ARTS-第8周-190506

Algorithm
Longest Common Prefix

Write a function to find the longest common prefix string amongst an array of strings.
If there is no common prefix, return an empty string “”.
Example 1:
Input: [“flower”,“flow”,“flight”]
Output: “fl”
Example 2:
Input: [“dog”,“racecar”,“car”]
Output: “”
Explanation: There is no common prefix among the input strings.
Note:
All given inputs are in lowercase letters a-z.

找出字符串数组中最长的共同前缀字符串,思路比较简单,直接逐位遍历查找最长共同字符串前缀。

static public string LongestCommonPrefix(string[] strs)
{
    string result = "";
    if (strs.Length == 0)
    {
        return result;
    }
    int maxlength = strs[0].Length;
    for (int i = 1; i < strs.Length; i++)
    {
        if (maxlength > strs[i].Length)
        {
            maxlength = strs[i].Length;
        }
    }
    for (int i = 0; i < maxlength; i++)
    {
        int j = 1;
        for (j=1;j<strs.Length;j++)
        {
            if (strs[0][i] != strs[j][i])
            {
                break;
            }
        }
        if (j == strs.Length)
        {
            result += strs[0][i];
        }
        else
        {
            break;
        }
    }
    return result;
}

这个题目难度是easy,不过我在网站提供的解决方案页面,看到了很多相关类型问题的解题思路。有从中间开始遍历,也有两端遍历,也有二分法遍历,还有使用Trie字典树。我的解题思路属于纵向遍历。
继续了解下 Trie字典树(前缀树)的相关知识。
在这篇文章上:https://www.cnblogs.com/justinh/p/7716421.html
找到了和本文题目相关的介绍:

(5)字符串最长公共前缀
Trie树利用多个字符串的公共前缀来节省存储空间,当我们把大量字符串存储到一棵trie树上时,我们可以快速得到某些字符串的公共前缀。
举例:
给出N 个小写英文字母串,以及Q 个询问,即询问某两个串的最长公共前缀的长度是多少?
解决方案:首先对所有的串建立其对应的字母树。此时发现,对于两个串的最长公共前缀的长度即它们所在结点的公共祖先个数,于是,问题就转化为了离线(Offline)的最近公共祖先(Least Common Ancestor,简称LCA)问题。
而最近公共祖先问题同样是一个经典问题,可以用下面几种方法:

  1. 利用并查集(Disjoint Set),可以采用采用经典的Tarjan 算法;
  2. 求出字母树的欧拉序列(Euler Sequence )后,就可以转为经典的最小值查询(Range Minimum Query,简称RMQ)问题了;

Review
Trie Data Structure (EXPLAINED)
https://www.youtube.com/watch?v=-urNrIAQnNo
简单的介绍了字典树的基本结构,字典树的创建和删除操作。就是语速有点慢,说的还是比较清晰。
Tips
C#
当月第一天:

//当月第一天的0时0分0秒
DateTime firstday =  DateTime.Now.AddDays(1 - DateTime.Now.Day).Date;
//如果不考虑时间,只需要日期
string firstday_str = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1).ToString("yyyy-MM-dd");

当月最后一天:

//当月最后一天最后一秒
DateTime.Now.AddDays(1 - DateTime.Now.Day).Date.AddMonths(1).AddSeconds(-1)

Share

  • C#创建简单的字典树
class TrieNode
    {
        public Dictionary<string, TrieNode> dic_value = new Dictionary<string, TrieNode>();
        public bool hasLeaf=false;
        public string leafvalue = "";
    }

    class SimpleTrieTree
    {
        public TrieNode rootNode = null;
        public SimpleTrieTree()
        {
            rootNode = new TrieNode();
        }
        public void AddNewWord(string new_word)
        {
            string word = new_word;
            TrieNode current_node = rootNode;
            while (word.Length > 0)
            {
                string first_s = word.Substring(0,1);
                if (current_node.dic_value.ContainsKey(first_s))
                {
                    current_node = current_node.dic_value[first_s];
                }
                else
                {
                    current_node.dic_value.Add(first_s, new TrieNode());
                    current_node = current_node.dic_value[first_s];
                }
                word = word.Substring(1);
                if (word.Length == 0 && current_node.hasLeaf==false)
                {
                    current_node.hasLeaf = true;
                    current_node.leafvalue = new_word;
                }
            }
        }
    }

使用字典树的方法解答本文的算法题:

static public string LongestCommonPrefix_tree(string[] strs)
{
     SimpleTrieTree simpleTrieTree = new SimpleTrieTree();
     for (int i = 0; i < strs.Length; i++)
     {
         if (strs[i].Length > 0)
         {
             simpleTrieTree.AddNewWord(strs[i]);
         }
         else
         {
             return "";
         }
     }
     string result = "";
     TrieNode current_node = simpleTrieTree.rootNode;
     while (true)
     {
         if (current_node != null && current_node.dic_value.Count == 1 && !current_node.hasLeaf)
         {
             string cur_key = current_node.dic_value.Keys.ElementAt(0);
             result += cur_key;
             current_node = current_node.dic_value[cur_key];
         }
         else
         {
             break;
         }
     }
     return result;
 }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值