No need for a double cycle: :
You are given N counters, initially set to 0, and you have two possible operations on them:
- increase(X) − counter X is increased by 1,
- max counter − all counters are set to the maximum value of any counter.
A non-empty zero-indexed array A of M integers is given. This array represents consecutive operations:
- if A[K] = X, such that 1 ≤ X ≤ N, then operation K is increase(X),
- if A[K] = N + 1 then operation K is max counter.
For example, given integer N = 5 and array A such that:
A[0] = 3 A[1] = 4 A[2] = 4 A[3] = 6 A[4] = 1 A[5] = 4 A[6] = 4
the values of the counters after each consecutive operation will be:
(0, 0, 1, 0, 0) (0, 0, 1, 1, 0) (0, 0, 1, 2, 0) (2, 2, 2, 2, 2) (3, 2, 2, 2, 2) (3, 2, 2, 3, 2) (3, 2, 2, 4, 2)
The goal is to calculate the value of every counter after all operations.
Assume that the following declarations are given:
struct Results {
int * C;
int L;
};
Write a function:
struct Results solution(int N, int A[], int M);
that, given an integer N and a non-empty zero-indexed array A consisting of M integers, returns a sequence of integers representing the values of the counters.
The sequence should be returned as:
- a structure Results (in C), or
- a vector of integers (in C++), or
- a record Results (in Pascal), or
- an array of integers (in any other programming language).
For example, given:
A[0] = 3 A[1] = 4 A[2] = 4 A[3] = 6 A[4] = 1 A[5] = 4 A[6] = 4
the function should return [3, 2, 2, 4, 2], as explained above.
Assume that:
- N and M are integers within the range [1..100,000];
- each element of array A is an integer within the range [1..N + 1].
Complexity:
- expected worst-case time complexity is O(N+M);
- expected worst-case space complexity is O(N), beyond input storage (not counting the storage required for input arguments).
Elements of input arrays can be modified.
Copyright 2009–2015 by Codility Limited. All Rights Reserved. Unauthorized copying, publication or disclosure prohibited.
My solution is:
1 struct Results solution(int N, int A[], int M) { 2 struct Results result; 3 // write your code in C99 4 result.C = malloc(sizeof(int)*N); 5 result.L = N; 6 int max = 0; 7 int tempMax = 0; 8 int i; 9 10 for(i=0;i<N;i++) 11 { 12 result.C[i]=0; 13 } 14 15 for(i=0;i<M;i++) 16 { 17 if(A[i]<=N) 18 { 19 if(result.C[A[i]-1]<max) 20 { 21 result.C[A[i]-1] = max+1; 22 } 23 else 24 { 25 result.C[A[i]-1]++; 26 } 27 28 if(tempMax<result.C[A[i]-1]) 29 { 30 tempMax = result.C[A[i]-1]; 31 } 32 } 33 else 34 { 35 max = tempMax; 36 } 37 } 38 39 for(i=0;i<N;i++) 40 { 41 if(result.C[i]<max) 42 { 43 result.C[i]=max; 44 } 45 } 46 return result; 47 }
Pay attention to the last for cycle;
我将所有小于max的值通过最后一个循环同步到了max,而在原来的循环中,如果没有更新这个节点的值,则即使它小于max,也不会去更新。
这样,就避免了每一次max操作时,对所有的节点进行遍历,将时间复杂度从N*M,降到了N+M