【问题标题】:Optimizing Python Algorithm for a particular Use Case using Pre-Computing使用预计算针对特定用例优化 Python 算法
【发布时间】:2018-02-27 17:28:18
【问题描述】:

我正在尝试解决此处提到的问题的特定变体:

给定一个字符串 s 和一个字符串 t,检查 s 是否是 t 的子序列。

我写了一个算法,可以很好地解决上述问题:

def isSubsequence(s, t):
        """
        :type s: str
        :type t: str
        :rtype: bool
        """
        i = 0

        for x in t:
            if i<len(s) and x==s[i]:
                i = i + 1

        return i==len(s)

现在有一个特定的用例:

如果有很多传入的 S,比如说 S1, S2, ... , Sk 其中 k >= 10 亿,并且你想一一检查 T 是否有它的子序列。

有个提示:

/**
 * If we check each sk in this way, then it would be O(kn) time where k is the number of s and t is the length of t. 
 * This is inefficient. 
 * Since there is a lot of s, it would be reasonable to preprocess t to generate something that is easy to search for if a character of s is in t. 
 * Sounds like a HashMap, which is super suitable for search for existing stuff. 
 */

但是逻辑似乎颠倒了上述算法的逻辑,如果遍历 s 并使用 hashmap 在 t 中搜索字符,它并不总是正确的,因为 t 的 hashmap 将只有 1 个索引该字符并且无法保证订单会被保留。

那么,我被困在如何针对上述用例优化算法?

感谢您的帮助。

【问题讨论】:

  • ts 的预期大小是多少?
  • t 可能非常大,s 必须小于 t 才能使子序列属性有效。

标签: python algorithm data-structures hash hashmap


【解决方案1】:

对于小于len(t)的每个i,以及出现在t中的每个字符c,从(i,c)-&gt;j进行映射,其中j是第一个索引>=i在其中c 出现。

然后您可以遍历每个 Sk,使用映射来查找每个所需字符的下一次出现(如果存在)。

这实质上是在创建一个与t (https://en.wikipedia.org/wiki/Deterministic_finite_automaton) 的子序列匹配的确定性有限自动机。

【讨论】:

    【解决方案2】:

    您可以预处理t 以创建所有可能子序列的列表(请记住t 将具有2^len(t)-1 子序列)。您可以将其转换为哈希表,然后遍历您的s 列表,检查表中的每个s。优点是您不必为每个s 迭代t

    顺便说一句,如果您在预处理t 以获取所有子序列的列表时遇到困难,您应该查看powerset 及其在python 中的实现。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-10-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-29
      相关资源
      最近更新 更多