【算法题】根据另一个数组的值来修改计算器数组的值
这个也是Codility上面的一个算法题
是说有一个计算器数组int[N] countArray, 数组A中包括N个元素, 初始化值都为0
也就是说 countArray = [0,0,0,0.....O]
现在对这个数组有2种操作:
Operation 1: increase(X) 代表数计数器组countArray中第X个元素的值加1 =》 比如increase(3) 就表示计数器数组countArray中第3个元素的值加1 也就是 countArray[2] += 1;
Operation 2: max counter 代表把计数器数组countArray中的所有元素,全部设置为当前计算器数组countArray中的最大值
然后现在有一个操作数组A, 包含M个整数 int[M] A 我们现在要根据操作数组A中元素的值,来对计数器数组countArray的值进行变更 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.
比如我们给一个计算器数组int[5] countArray, 也就是说计数器数组countArray有5个元素,N=5
然后操作数组A如下,操作数值A里面有7个元素,也就是说M=7, 列出如下
A[0] = 3 A[1] = 4 A[2] = 4 A[3] = 6 A[4] = 1 A[5] = 4 A[6] = 4
我们现在来看,如何根据操作数组A来更新计数器数组countArray的值
A[0] = 3, 满足 1 <= 3 <= 5, 所以操作0的结果就是 increase(3) => 也就是对计数器数组的第3位元素增加1 ,也就是说 countArray[2] += 1 , 结果如下 (0, 0, 1, 0, 0)
A[1] = 4, 满足 1 <= 4 <= 5, 所以操作1的结果就是increase(4) => 也就睡对计数器数组的第4位元素增加1, 也就是说 countArray[3] += 1, 结果如下
(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)
Write a function: class Solution { public int[] solution(int N, int[] A); } that, given an integer N and a non-empty array A consisting of M integers, returns a sequence of integers representing the values of the counters.
参数中的N代表计数器数组countArray包含N个元素, A是操作数组,包含M个元素, 返回操作完成后的计数器数组countArray 比如上面的例子,返回的最终计数器数组countArray就是
[3, 2, 2, 4, 2]
N和M的范围是 [1..100,000]
操作数组A中元素值得范围是 [1...N+1]
这个题目的解法,为了减少时间复杂度,其中的一个关键点,就是要避免for循环的嵌套,也就是说一个for循环中里面又有一个for循环
所以当 A[i] = N + 1时,我们不是按照直接的方法,用for循环,给计算器数组中的每个值赋给当前计算器数组的最大值,而是用一个变量来存储当前计数器数组的最大值maxValue
等所有操作完成,我们在最后一步,对计数器数组进行for循环,如果某个位置的值 < maxValue,就用 maxValue 覆盖它
另外,为了尽可能的减少for循环,我们也不用for循环来给计数器数组赋予初值0, 而是创建一个初始值为0的临时变量tmpValue来完成
整个代码如下
class Solution { public int[] solution(int N, int[] A) { int MAX = 0, tmpValue = 0, oriArrValue; int[] countArray = new int[N]; for(int i = 0; i < A.length; i++) { oriArrValue = A[i]-1; if(A[i] <= N && A[i] >= 1) { countArray[oriArrValue] = Math.max(tmpValue,countArray[oriArrValue]) + 1; MAX = Math.max(MAX,countArray[oriArrValue]); }else if(A[i] == N + 1) { tmpValue = MAX; } } for(int i = 0; i < countArray.length; i++) countArray[i] = Math.max(countArray[i],tmpValue); return countArray; } }