字符重排算法实现正确性

时间:2017-01-16 01:32:49

标签: python algorithm python-2.7

我正在解决下面的问题并发布了我的两个不同实现方案的代码。我的问题是,我有两个版本的实现,第一个版本是(1)处理最高频率字符直到完成,然后处理另一个字符,(2)第二个版本实现,处理最高频率字符的一个字符,降低其频率一个,并将其放回堆中并获得下一个更高频率的字符进行处理。

我发布下面的两个版本的代码,我已经测试过,似乎两种算法总是正确的?两种版本的代码都有问题吗?感谢。

如果两个版本都是正确的,我更喜欢第一个版本,因为它没有更好的性能,因为它不会推回到堆中(这可能会导致堆内部重新排列)。

我的代码是用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
import heapq
def rearrange_v1(source, distance):
    freq_map = defaultdict(int)
    for s in source:
        freq_map[s] += 1
    h=[]
    heapq.heapify(h)
    for c,f in freq_map.items():
        heapq.heappush(h, (-f,c))
    result = [0] * len(source)
    write_index = 0
    while len(h) > 0:
        f,c = heapq.heappop(h)
        f = -f
        while write_index < len(result) and result[write_index] != 0:
            write_index += 1
        if write_index == len(result):
            return None
        i = write_index
        while f > 0 and i < len(source):
            result[i] = c
            i += distance
            f -= 1
        if f > 0:
            return None

    return result

def rearrange_v2(source, distance):
    freq_map = defaultdict(int)
    for s in source:
        freq_map[s] += 1
    h=[]
    heapq.heapify(h)
    for c,f in freq_map.items():
        heapq.heappush(h, (-f,c))
    result = [0] * len(source)
    write_index = 0
    last_pos = defaultdict(int)
    while len(h) > 0:
        f,c = heapq.heappop(h)
        f = -f
        while write_index < len(result) and result[write_index] != 0:
            write_index += 1
        if write_index == len(result):
            return None
        i = write_index
        if c not in last_pos:
            result[i] = c
            last_pos[c]= i
        else:
            i = last_pos[c] + distance
            while i < len(result) and result[i] != 0:
                i += 1
            if i >= len(result):
                return None
            result[i] = c
            last_pos[c] = i
        if f > 1:
            f -= 1
            heapq.heappush(h, (-f,c))

    return result

if __name__ == "__main__":
    print rearrange_v1('abb', 2)
    print rearrange_v1('aacbbc', 3)
    print rearrange_v1('geeksforgeeks', 3)
    print rearrange_v1('aaa', 2)
    print '============================'
    print rearrange_v2('abb', 2)
    print rearrange_v2('aacbbc', 3)
    print rearrange_v2('geeksforgeeks', 3)
    print rearrange_v2('aaa', 2)

0 个答案:

没有答案