쿼드압축 후 개수 세기
문제정의
정사각형의 0,1로 이루어진 2차원 배열을 압축하는 문제이다. 정사각형 영역 S가 한숫자로만 이루어져 있으면 그 숫자로 압축할 수 있다. 만약 그렇지 않으면 4개의 정사각형으로 나누어 압축할 수 있는지 확인한다. 이 과정을 반복했을 때 0의 개수와 1의 개수를 배열로 담아 반환하면 된다.
문제풀이
전체 코드는 다음과 같다. 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51package level2;
public class QuadCompress {
//프로그래머스 문제풀이 level2 쿼드압축 후 개수 세기
public static void main(String[] args) {
int[][] arr = {
{1,1,0,0},
{1,0,0,0},
{1,0,0,1},
{1,1,1,1}
};
int[] answer = new int[2];
answer[0] = ReturnCnt(0, arr.length-1, 0, arr.length-1, arr, 0);
answer[1] = ReturnCnt(0, arr.length-1, 0, arr.length-1, arr, 1);
}
public static int ReturnCnt(int start_r, int end_r, int start_c, int end_c, int[][] arr, int comp_num)
{
if(start_r == end_r)
return arr[start_r][start_c] == comp_num ? 1 : 0;
else
{
boolean canCompress = true;
for(int r = start_r; r <= end_r; r++)
{
for(int c = start_c; c <= end_c; c++)
{
if(arr[r][c] != comp_num)
canCompress = false;
}
}
if(canCompress)
return 1;
int middle_r = (end_r-start_r)/2 + start_r;
int middle_c = (end_c-start_c)/2 + start_c;
int first = 0, sec = 0, third = 0, fourth = 0;
first += ReturnCnt(start_r, middle_r, start_c, middle_c, arr, comp_num);
sec += ReturnCnt(start_r, middle_r, middle_c+1, end_c, arr, comp_num);
third += ReturnCnt(middle_r+1, end_r, start_c, middle_c, arr, comp_num);
fourth += ReturnCnt(middle_r+1, end_r, middle_c+1, end_c, arr, comp_num);
return first+sec+third+fourth;
}
}
}
시간복잡도에 대해 고민을 해보았는데, 최악의 경우는 단 하나도 압축이 안되는 경우이다. 일단 함수가 쪼개지는 횟수는 정사각형의 한 변의 길이를 \(n(n \ge 2)\)일 때, 등비수열의 합 공식에 의해 \(4*(4^n-1)\over(4-1)\)번이다. 쪼개진 영역들을 검사하는 횟수를 다 합하면 한번에 \(n^2\)이다. 따라서 총 시간복잡도는 \(O(n^2*4^n)\)이다.
테스트
이번 문제는 시간복잡도를 계산하는 것이 까다로웠다. 이제 재귀에 익숙해져 가는 것 같아 뿌듯하다.