【问题标题】:How to efficiently rearrange characters in a string so that there are no pairs? [duplicate]如何有效地重新排列字符串中的字符以便没有对? [复制]
【发布时间】:2014-11-01 19:57:33
【问题描述】:

最多有 10^5 个 A..Z 字符的字符串。任务是重新排列它,以便没有一个字符形成一行。对于多种解决方案,按字母顺序排在第一位的解决方案是正确的。当然,它必须在合理的时间内完成。

所以我尝试了两种方法,其中一种重新排列正确但效率非常低,我猜另一种逻辑错误。

慢慢接近。

  1. 对字符数组进行排序
  2. 原地重新排列,类似于插入排序(这就是它这么慢的原因)

不正确的方法(并不总是按字母顺序给出第一个答案)

  1. 排序
  2. 将元素从末尾开始移动到另一个数组,保持不变量
  3. 反向

我真的被卡住了,在这里想不出其他任何事情。

例子:

"HHABC" -> "ABHCH";
"CBAXXXX" -> "XAXBXCX";
"AAABBBCCCCCCCDDDDD" -> "ABABACBCDCDCDCDCDC";

这里是详细的模型求解算法。我认为我不允许发布实际代码,所以它是这样的:

  1. 构建直方图。它可以存储在 int 数组中,索引是 ascii 代码,因此不需要映射。
  2. 构建新字符串:
    • 每个字符按字母顺序排列,从 A 到 Z
    • 如果根据直方图没有这样的符号,移到下一个
    • 如果之前的书写符号相同,则移动到下一个(如果不是第一次迭代)
    • 写第一个找到的合适的字符
    • 减少直方图中的数字
    • 如果当前符号有 (length-i+2)/2(剩下的一半),则中断此循环并转到字符串中的下一个符号。

它比我最终写的那个烂摊子更短更简单(虽然它工作得很好,非常感谢你的帮助)。

【问题讨论】:

  • 您真的不需要对输入数据进行任何排序或重新排列。由于您只有 26 个可能的输入值,因此只需在 O(n) 中生成直方图,然后使用直方图 bin 计数来生成适当交错的输出序列,再次在 O(n) 中。
  • 我知道我的想法过于复杂。但现在我不能完全抓住这个想法。如果用简单的话,我该怎么做第二部分?

标签: arrays algorithm time-complexity


【解决方案1】:

好点 Paul R。如果您的直方图包含每个元素的出现次数,那么您可以按出现次数从高到低对这些桶进行排序。只要一个bucket中出现的次数不大于bucket的个数,应该可以组成一个可行的string。从最大的存储桶开始,循环遍历下一个最大存储桶中的每个匹配项,直至较小的存储桶。

例如,AAAABBCRRRSTT

AAAAA BB C RR S TT -> AAAAA BB RR TT C S

ABARATACASBRT

【讨论】:

  • 谢谢!在我阅读您的答案之前,我刚刚开始了解这个想法。我现在就去试试。听起来很简单。
  • 欢迎您!您可能还需要考虑使用这些存储桶并移动一些字符以使它们的大小更加相等。这样您就可以避免与那些非常频繁的输入字符发生冲突。
  • 但实际上答案是错误的。应该是 ABABACARARTST
  • 啊,现在我明白你的意思了,按字母顺序排在第一位的是正确的。您绝对可以对存储桶进行排序:AAAAA BB C RR S TT,但仍有一些潜在的冲突。你不得不说,如果桶[i]的长度
猜你喜欢
  • 2021-05-26
  • 1970-01-01
  • 2011-01-03
  • 2014-10-31
  • 1970-01-01
  • 1970-01-01
  • 2020-02-05
  • 2013-10-24
  • 1970-01-01
相关资源
最近更新 更多