Alogorithm

[Algorithm] 프로그래머스 - 쿼드압축 후 개수 세기(분할정복)

Daniel(빡일) 2022. 1. 5. 20:30
반응형

 

 

 

프로그래머스 문제입니다.

[문제설명]

0과 1로 이루어진 2n x 2n 크기의 2차원 정수 배열 arr이 있습니다. 당신은 이 arr을 쿼드 트리와 같은 방식으로 압축하고자 합니다. 구체적인 방식은 다음과 같습니다.

  1. 당신이 압축하고자 하는 특정 영역을 S라고 정의합니다.
  2. 만약 S 내부에 있는 모든 수가 같은 값이라면, S를 해당 수 하나로 압축시킵니다.
  3. 그렇지 않다면, S를 정확히 4개의 균일한 정사각형 영역(입출력 예를 참고해주시기 바랍니다.)으로 쪼갠 뒤, 각 정사각형 영역에 대해 같은 방식의 압축을 시도합니다.

arr이 매개변수로 주어집니다. 위와 같은 방식으로 arr을 압축했을 때, 배열에 최종적으로 남는 0의 개수와 1의 개수를 배열에 담아서 return 하도록 solution 함수를 완성해주세요.

 


[제한사항]

 

 

  • arr의 행의 개수는 1 이상 1024 이하이며, 2의 거듭 제곱수 형태를 하고 있습니다. 즉, arr의 행의 개수는 1, 2, 4, 8, ..., 1024 중 하나입니다.
    • arr의 각 행의 길이는 arr의 행의 개수와 같습니다. 즉, arr은 정사각형 배열입니다.
    • arr의 각 행에 있는 모든 값은 0 또는 1 입니다.

 

 


[입출력]


[입출력 예시]

예제 #1

  • 다음 그림은 주어진 arr을 압축하는 과정을 나타낸 것입니다.

예제 #2

  • 다음 그림은 주어진 arr을 압축하는 과정을 나타낸 것입니다.
  • 최종 압축 결과에 0이 10개, 1이 15개 있으므로, [10,15]를 return 해야 합니다.

[문제풀이]

function solution(arr) {
    let answer = [0, 0]
    
    function recursiveHelper(x, y, len) {
        
        // if len is 1, increase the number
        if (len === 1) return answer[arr[y][x]]++   
        
        let tmp = []
        
        for (let i = 0; i < len; i++) tmp = tmp.concat(arr[y+i].slice(x, x+len))
    
        const sum = tmp.reduce((acc, cur) => acc + cur, 0)

        if (sum === 0) return answer[0]++
        else if (sum === len*len) return answer[1]++
        
        len /= 2
        recursiveHelper(x, y, len) // 1사분면
        recursiveHelper(x+len, y, len) // 2사분면
        recursiveHelper(x, y+len, len) // 3사분면
        recursiveHelper(x+len, y+len, len) // 4사분면
    
    }
    
    recursiveHelper(0, 0, arr.length)
    
    return answer;
}

 

Idea: 

 

 

반응형