【问题标题】:Improve order complexity of getting alphabet order from sorted strings提高从排序字符串中获取字母顺序的顺序复杂性
【发布时间】:2019-02-28 14:04:23
【问题描述】:

假设我有一个按字典顺序排序的字符串列表(大小为 n),由 a-z 组成,但不是 a, b, c... 的词汇顺序。现在主要问题是我想找到字母表的顺序。所以我把问题分为两部分:

  1. 从列表中的字符串中查找有序的字母对。
  2. 将这些对作为边构建有向图。对图进行拓扑排序以获得顺序。

我的问题是关于第一个。

为了做 1.,我做了一个 O(n^2m) 循环:

vector<pair<char, char> > build_ordered_pairs(vector<string> words) {
    vector<pair<char, char> > ordered_pairs;
    for(int i=0;i<n;i++) {
        for(int j=i+1;j<n;j++) {
            k = 0;
            while(k < words[i].size() && k < words[j].size() && words[i][k] == words[j][k])
                k++;
            if(k < words[i].size() && k < words[j].size())
                ordered_pairs.push_back(make_pair(words[i][k], words[j][k]));
        }
    }
    return ordered_pairs;
}

为了改善这一点,我们可以将字符串放入 trie 中,然后从 trie 的每个级别获取对。但这又是 n 的二次方。我们能不能做得更好,比如 nlogn 或者 n?

我们可能会一次又一次地得到相同的配对。那么我们是否可以检查某个对不是必需的,因此我们可以在同时构建有向图的同时跳过它。提前致谢。

输入输出对示例:

words = {"baa", "abcd", "abca", "cab", "cad"}
required = {'b', 'd', 'a', 'c'}

P.S : 也标记为 python,因为两者中的解决方案/建议都对我有用。

【问题讨论】:

  • @blhsing,使用示例输入输出对进行编辑。谢谢。

标签: python c++ algorithm


【解决方案1】:

您正在检查的字符串对比您需要的多。您只需要检查连续的字符串对,而不是所有对。通过比较字符串 0 和 3 获得的信息隐含在 0-1、1-2 和 2-3 比较中,拓扑排序可以为您处理。拓扑排序应该运行更快,输入中的无关边也更少。

【讨论】:

    【解决方案2】:

    一直致力于实际实现,但@user2357112 已经解释了它的要点。由于列表已经按字典顺序排序,您可以在遍历列表时简单地跟踪最后一个单词的第一个字母,如果它与当前单词的第一个字母相同,则将当前单词的其余部分放入一个列表,直到当前单词的第一个字母与最后一个单词的第一个字母不同,此时传递列表以进行递归调用。这个实现的平均时间复杂度是 O(n*log(n))。

    这是 Python 中的一个实现(使用collections.deque 进行高效的popleft 操作):

    from collections import deque
    def build_ordered_pairs(words):
        output = []
        if len(words) < 2:
            return output
        last_letter = None
        same_prefix = deque()
        while words:
            letter, *rest = words.popleft()
            if letter == last_letter:
                same_prefix.append(rest)
            else:
                if last_letter:
                    output.append((last_letter, letter))
                output.extend(build_ordered_pairs(same_prefix))
                same_prefix = deque([rest])
            last_letter = letter
        output.extend(build_ordered_pairs(same_prefix))
        return output
    

    这样:

    words = deque(["baa", "abcd", "abca", "cab", "cad"])
    print(build_ordered_pairs(words))
    

    会输出:

    [('b', 'a'), ('a', 'c'), ('d', 'a'), ('b', 'd')]
    

    由于您已经了解拓扑排序,因此我不会详细说明其余的实现。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-14
      • 2020-04-16
      • 2015-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多