본문 바로가기
📖 Coding Test/Codility

[Swift] Codility Lesson 4 - MaxCounters

by hyebin (Helia) 2022. 7. 23.

문제

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:

public func solution(_ N : Int, _ A : inout [Int]) -> [Int]

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

 

문제 링크
 

MaxCounters coding task - Learn to Code - Codility

Calculate the values of counters after applying all alternating operations: increase counter by 1; set value of all counters to current maximum.

app.codility.com

GitHub
 

GitHub - yoohyebin/swift

Contribute to yoohyebin/swift development by creating an account on GitHub.

github.com

 

문제 분석

  • 정수 N과 정수형 배열 A가 입력으로 주어진다.
  • 0으로 초기화된 N개의 요소를 갖고 있는 counter를 생성하여 동작을 수행한다.
    • 증가: A[k] = X, 1 ≤ X ≤ N, counter[X]를 1 증가시킨다.
    • max counter: A[K] = N + 1, 모든 counter의 값을 counter 요소들 중 최댓값으로 바꾼다.

 

해결방안 1 - 실패

  1. N개의 0으로 초기화된 re 배열 생성
  2. 입력된 배열 A의 요소 값이 N+1이라면 배열 re의 모든 요소들을 최댓값으로 변경
  3. 입력된 배열 A의 요소 값이 N+1이 아니라면 re[요소 값]을 1 증가

Solution 1

public func solution(_ N : Int, _ A : inout [Int]) -> [Int] {
    var re: [Int] = Array(repeating: 0, count: N)

    for i in A{
        if i == N+1{
            re = Array(repeating: re.max()!, count: N)
        }else{
            re[i-1] += 1
        }
    }
    return re
}

  • 입력이 큰 경우 timeout 오류 발생
  • max( )의 시간 복잡도는 O(N)
  • Array(repeating:, count:)의 시간 복잡도는 O(배열 길이)

 

해결방안 2 - 성공

  1. N개의 0으로 초기화된 counter 배열 생성
  2. counter배열의 최댓값을 저장하기 위한 변수 maxValue와 max counter 동작을 후처리 하기 위한 변수 maxCounter 선언
  3. 배열 A의 요소를 하나씩 확인 <배열 A의 요소  = i>
    • i가 N+1이라면, maxCounter 변수에 현재 counter 배열의 최댓값이 담겨있는 maxValue 값을 넣음
    • i가 N+1이 아니라면
      1. counter[i-1]이 maxCounter보다 작다면 counter[i-1]을 maxCounter로 변경
      2. counter[i-1]을 1 증가
      3. 최댓값을 담은 maxValue 변수와 비교하여 최댓값 update
  4. counter 배열에서 maxCounter 보다 작은 값이 있나 순서대로 탐색, 작은 값이 있다면 maxCounter 값으로 변경

Solution 2

public func solution(_ N : Int, _ A : inout [Int]) -> [Int] {
    var counter: [Int] = Array(repeating: 0, count: N)
    var maxValue = 0, maxCounter = 0

    for i in A{
        if i == N+1{
            maxCounter = maxValue
        }else{
            if counter[i-1] < maxCounter{
                counter[i-1] = maxCounter
            }
            counter[i-1] += 1
            maxValue = max(counter[i-1], maxValue)
        }
    }
    for index in 0..<counter.count{
        if counter[index] < maxCounter {counter[index] = maxCounter}
    }

    return counter
}

  • 시간 복잡도: O(N + M)
반응형

댓글