본문 바로가기
알고리즘

[Codility] Lesson 4: Counting Elements - MaxCounters (javascript)

by 윤-찬미 2021. 3. 18.

문제

 

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 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.

Write a function:

function solution(N, 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.

Result array should be returned as an array of integers.

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.

Write an efficient algorithm for the following assumptions:

  • 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].

 

해결방법 1

function solution(N, A) {
    let lastMax = 0;
    let max = 0;
    const reSet = new Array(N).fill(0);
    A.forEach((element, i) => {
        if(element < N+1) {
            reSet[element-1]++;
            lastMax = reSet[element-1];
            if(max <= lastMax) {
               max =  lastMax;
            }
        } else {
            reSet.fill(max);
        }
    })
    return reSet;
}

 

타임에러가 나는걸 보니 forEach 안에서 fill을 해준게 문제 인듯하다 저렇게 되면 N**2가 나올테니..

 

해결방법 2

function solution(N, A) {
    let lastMax = 0;
    let max = 0;
    const reSet = new Array(N).fill(0);
    A.forEach((element, i) => {
        if(element < N+1) {
            if(reSet[element-1] < lastMax) {
                reSet[element-1] = lastMax;
            } 
            reSet[element-1]++;
            if(max < reSet[element-1]) {
                max = reSet[element-1];
            }
        } else {
            lastMax = max;
        }
    })
    for(let i = 0; i < N; i++) {
        if(reSet[i] < lastMax) {
            reSet[i] = lastMax
        }
    }
    return reSet;
}

방법을 좀 바꿨다.

lastMax값을 두어서 N < reSet[element-1] 일경우가 나오면 해당 값을 max값으로 두고 max값이 나온경우에는 한번더 조건을 둬서 해당 요소가 max값보다 작을경우 해당요소를 max값으로 대체해 주었다. 어차피 전체 배열의 요소들을 N < reSet[element-1] 인경우는 모든 요소들이 max값보다 당연히 다 커야 하기 때문이다.

 

간단한거 같으면서도 생각할게 은근 많아서 어려웠다.

난 아직 멀었나보다 ㅜㅜ ㅜㅜ ㅜㅜ

'알고리즘' 카테고리의 다른 글

NODE.JS 기반으로 알고리즘 풀때 입력받는 방법  (1) 2021.02.26