PassingCars in Codility using Python

Question:

I have a coding challenge next week as the first round interview. The HR said they will use Codility as the coding challenge platform. I have been practicing using the Codility Lessons.

My issue is that I often get a very high score on Correctness, but my Performance score, which measure time complexity, is horrible (I often get 0%).

Here’s the question:
https://app.codility.com/programmers/lessons/5-prefix_sums/passing_cars/

My code is:

def solution(A):
    N = len(A)
    my_list = []
    count = 0
    for i in range(N):
        if A[i] == 1:
            continue
        else:
            my_list = A[i + 1:]
            count = count + sum(my_list)
    print(count)
    return count

It is supposed to be O(N) but mine is O(N**2).

  1. How can someone approach this question to solve it under the O(N) time complexity?

  2. In general, when you look at an algorithm question, how do you come up with an approach?

Asked By: Jun Jang

||

Answers:

You should not sum the entire array each time you find a zero. That makes it O(n^2). Instead note that every zero found will give a +1 for each following one:

def solution(A):
    zeros = 0
    passing = 0
    for i in A:
        if i == 0:
            zeros += 1
        else:
            passing += zeros
    return passing
Answered By: Stephen Rauch

You may check all codility solutions as well as passingcars example.

Don’t forget the 1000000000 limit.

def solution(a):
    pc=0
    fz=0

    for e in a:
        if pc>1000000000:
            return -1
        if e==0:
            fz+=1
        else:
            pc+=fz           

    return pc
Answered By: 555

Regarding the above answer, it is correct but missing checking the cases where passing exceeds 1000000000.

Also, I found a smarter and simple way to count the pairs of cars that could be passed where you just count all existing ones inside the array from the beginning and inside the loop when you find any zero, you say Ok we could possibly pair all the ones with this zero (so we increase the count) and as we are already looping through the whole array, if we find one then we can simply remove that one from ones since we will never need it again.

It takes O(N) as a time complexity since you just need to loop once in the array.

def solution(A):

    ones = A.count(1)   
    c = 0

    for i in range(0, len(A)):
        if A[i] == 0:
            c += ones
        else: ones -= 1

    if c > 1000000000:
        return -1
    return c

In a loop, find indices of zeros in list and nb of ones in front of first zero. In another loop, find the next zero, reduce nOnesInFront by the index difference between current and previous zero

def solution(A):
    count = 0; zeroIndices = []
    nOnesInFront = 0; foundZero = False
    for i in range(len(A)):
        if A[i] == 0: 
            foundZero = True
            zeroIndices.append(i)
        elif foundZero: nOnesInFront += 1;
    if nOnesInFront == 0: return 0 #no ones in front of a zero
    if not zeroIndices: return 0 #no zeros
    iPrev = zeroIndices[0]
    count = nOnesInFront
    for i in zeroIndices[1:]:
        nOnesInFront -= (i-iPrev) - 1 #decrease nb of ones by the differnce between current and previous zero index
        iPrev = i
        count += nOnesInFront
    if count > 1000000000: return -1
    else: return count

Here are some tests cases to verify the solution:

print(solution([0, 1, 0, 1, 1])) # 5
print(solution([0, 1, 1, 0, 1])) # 4
print(solution([0])) # 0
print(solution([1])) # 0
print(solution([1, 0])) # 0
print(solution([0, 1])) # 1
print(solution([1, 0, 0])) # 0
print(solution([1, 0, 1])) # 1
print(solution([0, 0, 1])) # 2
Answered By: Samil
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.