代码之家  ›  专栏  ›  技术社区  ›  Deepak Saini

从排序字符串中获得字母顺序的顺序复杂度提高

  •  0
  • Deepak Saini  · 技术社区  · 7 年前

    假设我有一个列表(大小n)的字典排序字符串(max size m)在一些语言中包括 a-z 但不是词汇顺序 a, b, c... . 现在主要的问题是我想找出字母表的顺序。所以我把问题分为两部分:

    1. 从这些对中构造一个有向图作为边。对图进行拓扑排序以获得顺序。

    我的问题是关于第一个。

    为了完成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也一样,因为这两种方法中的解决方案/建议对我都有用。

    2 回复  |  直到 7 年前
        1
  •  3
  •   user2357112    7 年前

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

        2
  •  1
  •   blhsing    7 年前

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

    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')]
    

    因为您已经知道拓扑排序,所以我不详细说明实现的其余部分。