[codility] Lesson 2 Counting Elements

FrogRiverOne

def solution(X, A):
    positions = set()
    for i in range(len(A)):
        if A[i] not in positions:
            positions.add(A[i])
        if len(positions) == X:
            return i
    return -1

PremCheck

def solution(A):
    dict_set = set(x + 1 for x in range(len(A)))
    for a in A:
        if a in dict_set:
            dict_set.remove(a)
        else:
            return 0
    if not dict_set:  # set is empty
        return 1
    return

MissingInteger

def solution(A):
    s = set()
    while A:
        s.add(A.pop())
    for i in range(1, len(s) + 2):
        if i not in s:
            return i
    return 1

MaxCounter

这个题必须要说一下,按照正常思路提交后performance完全失败。根据testcase提示得知是max方法出的问题。

自己分析发现每一次max操作相当于重置所有数字,然后中途的重置没有实际意义,最后一次重置才是有价值的。

然而还是没有想到一个好的方式,后面google别人的代码才发现increase方法需要及时更新最后一次重置的值。

这个思路在于每一次重置时不实际操作数组A,所以复杂度是O(1),只要最后做一次真实重置,达到O(M+N)

class Counters(object):
    def __init__(self, n):
        self.counter_list = [0] * n
        self.max_counter = 0
        self.last_max_value = 0
        self.size = n
        
    def increase(self, x):
        x -= 1  # 0-start-index
        if self.counter_list[x] < self.last_max_value:  # reset after last_max_update
             self.counter_list[x] = self.last_max_value
        self.counter_list[x] += 1
        if self.counter_list[x] > self.max_counter:
            self.max_counter = self.counter_list[x]

    def max(self):  # cache last max update value
        self.last_max_value = self.max_counter
        
    def current_list(self):
        for i in range(self.size):
            if self.counter_list[i] < self.last_max_value:  # position not updated
                self.counter_list[i] = self.last_max_value
        return self.counter_list

def solution(N, A):
    counters = Counters(N)
    for a in A:
        if a == N + 1:
            counters.max()
        else:
            counters.increase(a)
    return counters.current_list()
原文地址:https://www.cnblogs.com/t--c---/p/4762243.html