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)问题。
而最近公共祖先问题同样是一个经典问题,可以用下面几种方法:
- 利用并查集(Disjoint Set),可以采用采用经典的Tarjan 算法;
- 求出字母树的欧拉序列(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;
}