美文网首页
Codility 8.2 EquiLeader [leader]

Codility 8.2 EquiLeader [leader]

作者: 波洛的汽车电子世界 | 来源:发表于2019-08-18 19:45 被阅读0次

Find the index S such that the leaders of the sequences A[0], A[1], ..., A[S] and A[S + 1], A[S + 2], ..., A[N - 1] are the same.

Task description
A non-empty array A consisting of N integers is given.

The leader of this array is the value that occurs in more than half of the elements of A.

An equi leader is an index S such that 0 ≤ S < N − 1 and two sequences A[0], A[1], ..., A[S] and A[S + 1], A[S + 2], ..., A[N − 1] have leaders of the same value.

For example, given array A such that:

    A[0] = 4
    A[1] = 3
    A[2] = 4
    A[3] = 4
    A[4] = 4
    A[5] = 2
we can find two equi leaders:

0, because sequences: (4) and (3, 4, 4, 4, 2) have the same leader, whose value is 4.
2, because sequences: (4, 3, 4) and (4, 4, 2) have the same leader, whose value is 4.
The goal is to count the number of equi leaders.

Write a function:

def solution(A)

that, given a non-empty array A consisting of N integers, returns the number of equi leaders.

For example, given:

    A[0] = 4
    A[1] = 3
    A[2] = 4
    A[3] = 4
    A[4] = 4
    A[5] = 2
the function should return 2, as explained above.

Write an efficient algorithm for the following assumptions:

N is an integer within the range [1..100,000];
each element of array A is an integer within the range [−1,000,000,000..1,000,000,000].

思路:这道题是Dominator的拓展,意思是将数组一分为二,左右的Leader相同,求这样的分割点个数。
这道题不用求三次Leader,只要求一次。因为:如果一个数在左右子数组中都是Leader,那么它必然也是原数组的Leader。
因此我们只需找出原数组的Leader并记录Leader出现的次数leader_count,然后再枚举分割点,求Leader在左子数组出现的次数leader_left,再看leader_left和leader_count - leader_left是否都大于各自的数组一半长。

#66%
#Detected time complexity:
#O(N ** 2)
def solution1(A):
    # write your code in Python 3.6
    size = 0
    leader = -1
    index = -2
    result = 0
    count_left = 0
    
    for i in range(len(A)):
        if size ==0:
            leader = A[i]
            size +=1
            index +=1
        else:
            if leader !=A[i]:
                size -=1
            else:
                size+=1
    leader_count = len([i for i in A if i == leader]) # count
    if leader_count <= len(A)//2:
        return 0
        
    for i in range(len(A)-1):
        if A[i] == leader:
            count_left +=1
        if count_left>len(A[:i+1])//2 and leader_count-count_left>len(A[i+1:])//2:
            result +=1   
    return result
#Detected time complexity:
#O(N)
#100%
def solution2(A):
    # write your code in Python 3.6

    A_len = len(A)
    candidate = -1
    candidate_count = 0
    candidate_index = -1
    # Find out a leader candidate
    for index in range(A_len):
        if candidate_count == 0:
            candidate = A[index]
            candidate_index = index
            candidate_count += 1
        else:
            if A[index] == candidate:
                candidate_count += 1
            else:
                candidate_count -= 1
    # Make sure the candidate is the leader
    leader_count = len([number for number in A if number == candidate])
    if leader_count <= A_len//2:
        # The candidate is not the leader
        return 0
    else:
        leader = candidate
    equi_leaders = 0
    leader_count_so_far = 0
    for index in range(A_len):
        if A[index] == leader:
            leader_count_so_far += 1
        if leader_count_so_far > (index+1)//2 and leader_count-leader_count_so_far > (A_len-index-1)//2:
            # Both the head and tail have leaders of the same value
            # as "leader"
            equi_leaders += 1
    return equi_leaders

复杂度分析:def1是我写的,时间复杂度为O(N**2),def2来源于code says,时间复杂度为O(N),这里分析一下原因:用了大量的len(A)以及slice。
首先,能用常数就不用len(A),可以用for i in A 或者len_a = len(A),因为每个len() 都是O(N)。
其次,慎重用len(a[i:])和len(a[:i]),这是在不停的在产生slice的copy,是整个程序里面最大的开销。
最后,不要随便用count啊,每一次count都是一次遍历,复杂度是O(n)
总之,能用常数就不用built-in func。
程序最终版,Detected time complexity:O(N)

    # write your code in Python 3.6
    A= [4,3,4,4,4,2]
    len_A = len(A)
    size = 0
    leader = -1
    index = -2
    result = 0
    count_left = 0
    
    for i in A:
        if size ==0:
            leader = i
            size +=1
            index +=1
        else:
            if leader ==i:
                size +=1
            else:
                size-=1
    leader_count = len([i for i in A if i == leader]) # count
    if leader_count <= len_A//2:
        return 0
        
    for i in range(len_A):
        if A[i] == leader:
            count_left +=1
        if count_left>(i+1)//2 and leader_count-count_left>(len_A-i-1)//2:
            result +=1   
    return result

相关文章

网友评论

      本文标题:Codility 8.2 EquiLeader [leader]

      本文链接:https://www.haomeiwen.com/subject/dqhkjctx.html