【问题标题】:Merging and sorting n strings in O(n)在 O(n) 中合并和排序 n 个字符串
【发布时间】:2018-07-16 18:51:52
【问题描述】:

我最近在编码挑战中遇到了一个问题,我必须合并 n 个字母数字字符串,然后对新合并的字符串进行排序,同时只允许排序后的字符串中包含字母字符。现在,这将是相当直接的,除了添加的警告是算法必须是 O(n) (它没有指定这是时间复杂度还是空间复杂度或两者兼而有之)。

我最初的方法是将字符串连接成一个新字符串,只添加字母字符,然后在最后进行排序。我想提出一个更有效的解决方案,但我得到的时间比最初被告知的要少。没有任何排序算法(我知道)在 O(n) 时间内运行,所以我唯一能想到的是我可以增加空间复杂度并使用排序的哈希表(例如 C++ 映射)来存储每个字符的计数,然后按排序顺序打印哈希表。但由于这可能需要打印 n 个字符 n 次,我认为它仍然会以二次时间运行。另外,我使用的是 python,我认为它没有办法保持字典排序(也许可以)。

这个问题是否可以在 O(n) 时间和/或空间复杂度内解决?

【问题讨论】:

  • 计数排序是 O(n) 时间。它可能会起作用(尽管如果您考虑使用字母数字来包含所有 Unicode 字母数字的东西,那就更难了)。
  • [幽默] 考虑一下 Ramesh 教授 Existencial Sort 这是 O(1)

标签: python c++ string algorithm sorting


【解决方案1】:

如果我正确理解了要求,那么您只是对字符串中的字符进行排序?

ADFSACVB 变成 AABCDFSV

如果是这样,那么诀窍就是不要真正“排序”。你有一个固定(和少量)的值。因此,您可以简单地记录每个值并从中生成结果。

例如给定ABACBA

在第一遍中,递增由字符索引的数组中的计数器。这会产生:

[A] == 3 [B] == 2 [C] == 1

在第二遍输出计数器指示的每个字符的数量。 AAABBC

总而言之,您被告知要排序,但跳出框框思考,您真的需要计数 算法。

【讨论】:

  • 是的,这是我在 OP 中建议的解决方案,但这不是 O(n) 吗?任何字符的计数都没有上限。
  • 是的,它是 O(n)。建立计数器数组后,您会读取每个 n 字符。然后迭代固定大小的计数器数组。注意:不要使用问题中所述的字典。使用固定大小的数组。
  • 请记住,随着n 的增长,复杂度的顺序与趋势有关。因此,固定开销很快变得可以忽略不计,因为它是常量。这甚至适用于较大的开销; n 的阈值是 n 在成本中的“权重”。
【解决方案2】:
  1. 连接你的字符串(不是真的需要,你也可以计算单个字符串中的字符)
  2. 创建一个长度等于字符码总数的数组
  3. 通读您的连接字符串并计算在第 2 步创建的数组中出现的次数
  4. 通过读取 char freq 数组,构建一个输出数组,其中每个 char 重复的正确 nr。

因为每一步都是O(n)所以整个事情是O(n)

[@patatahooligan:在看到您的评论之前进行了此编辑,不小心重复了答案]

【讨论】:

    【解决方案3】:

    您的计数排序要走的路:按顺序为 26 个字母构建一个简单的计数表。遍历你的两个字符串,计算字母,忽略非字母。这是 O(n) 的一次通过。现在,只需浏览您的表格,按指示的次数打印每个字母。这也是 O(n),因为计数的 sum 不能超过 n。您没有打印n 个字母n 次:您打印了一个total n 个字母。

    【讨论】:

    • 对,所有计数必须加起来为 n。如果给我时间,我会得到这个,我认为我有......哦,好吧
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-12
    • 2017-01-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多