我正在解决以下问题,并发布了我的代码。我的问题是,我目前的实现在Python中使用了排序 -
我的代码是用Python 2.7编写的。
问题:
给定一个字符串和一个正整数d。给定字符串中可能会重复出现某些字符。重新排列给定字符串的字符,使得相同的字符离彼此至少有d个距离。请注意,可能会有许多可能的重新排列,输出应该是可能的重新排列之一。如果没有这样的安排,则应报告。
期望的时间复杂度是O(n),其中n是输入字符串的长度。
例子:
sorted(sorted_freq, reverse=True)
。我参考了一些其他的实现,它们使用了最大堆(http://www.geeksforgeeks.org/rearrange-a-string-so-that-all-same-characters-become-at-least-d-distance-away/)。我认为它们具有相同的时间复杂度,即O(n*log n)
(如果我计算错误,请随时更正)。所以我想知道除了排序之外,使用堆是否有任何性能上的好处?我的代码是用Python 2.7编写的。
问题:
给定一个字符串和一个正整数d。给定字符串中可能会重复出现某些字符。重新排列给定字符串的字符,使得相同的字符离彼此至少有d个距离。请注意,可能会有许多可能的重新排列,输出应该是可能的重新排列之一。如果没有这样的安排,则应报告。
期望的时间复杂度是O(n),其中n是输入字符串的长度。
例子:
Input: "abb", d = 2
Output: "bab"
Input: "aacbbc", d = 3
Output: "abcabc"
Input: "geeksforgeeks", d = 3
Output: egkegkesfesor
Input: "aaa", d = 2
Output: Cannot be rearranged
源代码:
from collections import defaultdict
def rearrange(source, distance):
freq = defaultdict(int)
for c in source:
freq[c] += 1
sorted_freq = []
for k,v in freq.items():
sorted_freq.append((v,k))
sorted_freq = sorted(sorted_freq, reverse=True)
result = [0] * len(source)
for i, (v,k) in enumerate(sorted_freq):
index = i
while index < len(result) and result[index] != 0:
index += 1
if index == len(result):
return None
count = v
while count > 0:
result[index] = k
index += distance
count -= 1
if index >= len(source) and count > 0:
return None
return result
if __name__ == "__main__":
print rearrange('abb', 2)
print rearrange('aacbbc', 3)
print rearrange('geeksforgeeks', 3)
print rearrange('aaa', 2)
O(n + m log m)
,因为在循环for i, (v,k) in enumerate(sorted_freq)
中,我循环的次数是唯一字符的数量(我认为在你的答案中,n
表示字符串的长度,m
表示字符串中唯一字符的数量)。如果我误解了你的评论,请随时纠正我。 - Lin Mam
次,这是唯一字符的数量。但是请考虑第一个while
循环执行的次数。在我给你的例子中,外部循环的第一次迭代中,index
被初始化为0
,并且将被执行0
次,因为result[0]
是0
。第二次时,index
为1
,循环执行0
次,因为result[1]
是0
。在第三轮中,事情变得更有趣,因为index
初始化为2
,而result
中的第一个空闲索引是20000
。第四轮中,index
初始化为3
,而第一个空闲索引是20001
。 - niemmistart
只向前移动,这意味着内部的while
循环最多会执行总共 n 次。 - niemmi