Lesson 4 question 3 MaxCounters

源地址

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;
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章