【问题标题】:Algorithm to Find if M28K is unique查找 M28K 是否唯一的算法
【发布时间】:2012-08-09 17:53:28
【问题描述】:

今天小弟问了我一个问题,问题如下:

Given a list of strings & string M28K, where M28K represents a string which starts
from M, ends with K and has 28chars in between . Find if M28K is unique in the 
list of strings or not?

我想出了以下算法来找到问题的解决方案:

对于每个字符串:

find string length(L)
  if(L==30) then
      if(str[0]=='M' && str[L-1]=='K') then
          verify rest of 28 characters are matching or not

就时间复杂度而言,该解决方案似乎效率不高。谁能给出一个更好的算法来解决这个问题?

【问题讨论】:

  • 定义“在字符串列表中是唯一的”。这是否意味着“M28K 只能在字符串列表中找到一次”,或者“M28K 不存在于字符串列表中”?无论哪种情况,我认为您能做的最好的事情就是 O(n) 时间,这就是您的解决方案!干得好。
  • efficient way to search for string in list of string? 的可能重复项或网站上的 100 个其他问题,询问如何在列表中查找字符串。我们知道它以什么字母开头和结尾的事实是无关紧要的。
  • @Kevin “在字符串列表中是唯一的”意味着,给定的字符串列表根本不包含 M28K
  • @Kevin Jaguars 算法不是 O(n)。请看我的解释。

标签: string algorithm


【解决方案1】:

我会选择散列。通常,因为这听起来像是一个算法作业问题,根据我的经验,我们不允许用散列来回答,因为它真的取决于你的散列函数。如果不够好,那么您将无法获得每个字符串的唯一值。

我会根据字符串中的字符将字符串列表构建成二叉排序树。维护一个算法,如果字符串按字母顺序位于头节点之前,则将其放在左侧,如果它位于头节点之后,则将其放在右侧。当然是递归的。我们有一棵树。现在允许最坏的情况,这将在 O(n) 时间内完成,这实际上只是一个链表,但是在 m 或 n 区域的某个地方有一个好的头节点,这个查找可以在 O(log n) 内完成.所以整个操作需要 O(n log n) 时间。

您提供的算法,最坏的情况将需要 O(n^2)。假设每个字符串有 30 个字符,并以 K 结尾并以 L 开头。除倒数第二个字符外。实际上,我们将搜索所有提供的字符串的 28 个字符。 n^2 用于查找所有字符串的大小。每个字符串都需要 O(n) 时间,使其成为 n^2 算法。在我的算法中,我们每次都将问题减半,这提供了更快的搜索速度。

【讨论】:

  • 但是O(n*log(n))不是比他原来的O(n)解慢吗?
  • @iSelkiies 你根本不需要找到长度。你可以试着计算一个字符串的长度,当你看到它超过30时,你可以停止计算当前字符串的长度,然后去比下一个字符串。
  • iSelkiies,我认为你在这里混淆了你的变量。找到一个以 null 结尾的字符串的长度确实是 O(n),其中 n 是字符串的长度。并且遍历列表是 O(n) 时间,其中 n 是列表的长度。由于 n 在这两者中代表不同的事物,因此您不能将它们一起平滑成 O(n^2) - 您需要替换其中一个字母,在这种情况下,算法是 O(m*n)。
  • +1 给 Kevin 在所有方面。这个答案似乎是使用n 来表示两个不同的东西(列表的长度和字符串的长度)。如果你正确地将它们分开,那么两个字符串的比较是O(m),这使得你的算法O(m*n log n)。 OP的算法是O(n*m),这是我们能做的最好的(因为列表没有开始排序,我们能做的最好的就是与每个字符串只比较一次。因为所有比较排序都必须查看每个元素至少一次,你不能通过首先对列表进行排序来做得更好).
  • @iSelkiies 你错了。假设字符串的长度为 O(m)。如果您使用我的方法,检查长度直到达到 30 - 如果您看到停止的 31 个字符,您将检查每个字符串的长度为 O(1),而忽略不相关的字符串。这肯定不是二次运行时间。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-12-08
  • 2014-06-27
  • 1970-01-01
  • 1970-01-01
  • 2018-02-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多