如何使性能 O(N) 而不是 O(N^2)?

How can I make the performance O(N) instead of O(N^2)?

我正在尝试了解如何使这个问题的时间复杂度更好:

A non-empty zero-indexed array A consisting of N integers is given. The consecutive elements of array A represent consecutive cars on a road.

Array A contains only 0s and/or 1s: 0 represents a car traveling east, 1 represents a car traveling west.

The goal is to count passing cars. We say that a pair of cars (P, Q), where 0 ≤ P < Q < N, is passing when P is traveling to the east and Q is traveling to the west.

For example, consider array A such that:

A[0] = 0   
A[1] = 1   
A[2] = 0   
A[3] = 1   
A[4] = 1 

We have five pairs of passing cars: (0, 1), (0, 3), (0, 4), (2, 3), (2, 4).

Write a function:

int solution(NSMutableArray *A);

that, given a non-empty zero-indexed array A of N integers, returns the number of pairs of passing cars.

The function should return −1 if the number of pairs of passing cars exceeds 1,000,000,000.

Assume that:

N is an integer within the range [1..100,000]; each element of array A is an integer that can have one of the following values: 0, 1.

Complexity:

expected worst-case time complexity is O(N); expected worst-case space complexity is O(1), beyond input storage (not counting the storage required for input arguments). Elements of input arrays can be modified.

解决方案:

   int solution(NSMutableArray *A) {
// write your code in Objective-C 2.0

int counter = 0;

for (int i = 0; i < A.count; i++) {
    if ([A[i] intValue] == 0) {
        for (int j = i; j < A.count; j++) {
            if ([A[j] intValue] == 1) {
                counter++;
            }
        }
    }
}


return counter;
}

现在,由于嵌套的 for 循环,解决方案的复杂度为 运行,复杂度为 O(N^2)。我似乎无法思考如何在 O(N) 时间内解决它。这不是家庭作业;我只是刷新面试算法。

类似的东西?

NSInteger solutionCountingDifferentDirections(NSMutableArray *A) {
    NSInteger multiplier = 1;
    NSInteger counter = 0;
    NSInteger firstCarDirection = A[0];
    for (NSInteger idx = 1; idx < A.count; idx++) {
        if (firstCarDirection == A[idx]) {
            multiplier++;
        }
        else {
            counter += multiplier;
        }
    }

    return counter;
}

编辑: @RNar 建议我们不计算第一辆向西行驶的汽车,所以这里是针对这种情况的解决方案:

NSInteger solutionCountingFromFirstEastDirection(NSMutableArray *A) {
    NSInteger multiplier = 0;
    NSInteger counter = 0;
    for (NSInteger idx = 0; idx < A.count; idx++) {
        if (A[idx] == 0) {
            multiplier++;
        }
        else {
            counter += multiplier;
        }
    }

    return counter;
}