源地址
https://app.codility.com/programmers/lessons/4-counting_elements/max_counters/
MaxCounters(計數器)
給定N個計數器,初始值爲0,對於他們你有兩個可能的操作
- increase(X) 計數器X遞增1
- max counter 所有的計數器被設定爲最大計數器的值
給定一個含有M個整數的非空數組A。這個數組代表如下操作:
- 如果 A[K] = X,而1 ≤ X ≤ N,那麼操作就是increase(X)
- 如果 A[K] = N+1,那麼操作就是max counter
比如,給定整數N= 5 ,和數組A如下:
A[0] = 3
A[1] = 4
A[2] = 4
A[3] = 6
A[4] = 1
A[5] = 4
A[6] = 4
在每一個連續操作之後計數器的值如下:
(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)
目標是計算在所有操作之後的各個計數器的值。
寫一個函數
class Solution {
public int[] solution(int N, int[] A);
}
給定一個整數N,和包含M個整數的非空數列A,返回代表各個計數器的值的一串整數。
結果集應該作爲一個整數數列返回。
比如,給定
A[0] = 3
A[1] = 4
A[2] = 4
A[3] = 6
A[4] = 1
A[5] = 4
A[6] = 4
函數應該返回[3, 2, 2, 4, 2]
假定:
- N和M是範圍在[1…100,000]的整數
- 數列A中的每個元素都是在範圍[1…N + 1]的整數
第一步
完全按照題中解釋的邏輯實現,時間複雜度感人。
public int[] solution(int N, int[] A) {
int[] B = new int[N];
int max = 0;
for (int a : A) {
if (a <= N) {
B[a - 1]++;
max = Math.max(max, B[a - 1]);
} else {
Arrays.fill(B, max);
}
}
return B;
}
第二步
更快的方法是每次max counter的時候,記錄下這個水平面的值,而不是把所有計數器的值重新設置。
public int[] solution(int N, int[] A) {
int[] B = new int[N];
int max = 0;
int level = 0;
for (int a : A) {
if (a <= N) {
if (B[a - 1] < level) {
B[a - 1] = level + 1;
} else {
B[a - 1]++;
}
max = Math.max(max, B[a - 1]);
} else {
level = max;
}
}
for (int i = 0; i < N; i++) {
if (B[i] < level) {
B[i] = level;
}
}
return B;
}