문제

https://programmers.co.kr/learn/courses/30/lessons/17679


코드

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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
private static final int ASCII = 32;
private static final char EMPTY = ' ';

public int solution(int m, int n, String[] board) {
int answer = 0;
char[][] charBoard = convertStringArrayToCharArray(m, n, board);

while (true) {
boolean isEnd = box(charBoard);

if (isEnd) {
break;
}

answer += delete(charBoard);
}

return answer;
}

public char[][] convertStringArrayToCharArray(int m, int n, String[] board) {
char[][] charBoard = new char[m][n];

int i = 0;
for (String str : board) {
char[] toChar = str.toCharArray();
charBoard[i] = toChar;
++i;
}

return charBoard;
}

public char toLowerCase(char value) {
return (char) ((value >= 65 && value <= 90) ? (value + ASCII) : value);
}

public boolean box(char[][] charBoard) {
boolean isEnd = true;

for (int i = 0; i < charBoard.length; i++) {
for (int j = 0; j < charBoard[i].length; j++) {
if (validation(i, j, charBoard)) {
char value = toLowerCase(charBoard[i][j]);
charBoard[i][j] = value;
charBoard[i][j+1] = value;
charBoard[i+1][j] = value;
charBoard[i+1][j+1] = value;

isEnd = false;
}
}
}

return isEnd;
}

private boolean validation(int i, int j, char[][] charBoard) {
if ((i + 1) == charBoard.length || (j + 1) == charBoard[0].length) {
return false;
}
char position = toLowerCase(charBoard[i][j]);

if (position == EMPTY) {
return false;
}

char moveX = toLowerCase(charBoard[i][j+1]);
char moveY = toLowerCase(charBoard[i+1][j]);
char moveXY = toLowerCase(charBoard[i+1][j+1]);

if (position != moveX) {
return false;
}

if (position != moveY) {
return false;
}

if (position != moveXY) {
return false;
}

return true;
}

private int delete(char[][] charBoard) {
int answer = 0;

for (int i = 0; i < charBoard.length; i++) {
for (int j = 0; j < charBoard[i].length; j++) {
if (charBoard[i][j] == EMPTY) {
continue;
}

if (charBoard[i][j] >= 97 && charBoard[i][j] <= 122) {
if (i != 0) {
for (int k = i; k > 0; k--) {
charBoard[k][j] = charBoard[k-1][j];
charBoard[k-1][j] = EMPTY;
}
} else {
charBoard[i][j] = EMPTY;
}

++answer;
}
}
}

return answer;
}

흐름

  1. String array로 넘어온 board를 2차원 array로 만든다.
  2. 무한루프를 돌면서 char로 만든 board array의 element들을 모두 꺼내면서
  3. 제약조건을 확인하여 모두 통과할 때만 true를 return 한다.
    1. 현재 element가 있는 위치가 맨 끝인지
    2. 현재 element가 빈 값인지
    3. 현재 element의 오른쪽 element와 값이 같지 않은지
    4. 현재 element의 아래쪽 element와 값이 같지 않은지
    5. 현재 element의 우하(右下)쪽 element와 값이 같지 않은지
  4. 제약조건을 통과하면 현재 위치에서 오른쪽, 아래쪽, 우하(右下)쪽 element들을 소문자로 만들고 삭제 할 블록이 남았으므로, false를 return 한다.
  5. 다시 board array를 반복하면서 element가 소문자인 경우
  6. 현재 높이가 0이라면 위에서 내려올 블록이 없으므로 바로 빈 값을 저장하고
  7. 0이 아니라면 현재 위치부터 값을 1씩 빼면서 위에 블록을 현재 위치에 저장 시키고 위 블록은 빈 값으로 저장한다.
  8. 블록을 제거 할 때 마다 제거시킨 블록 개수를 저장하는 변수를 증가시킨다.
  9. 삭제 할 블록이 없을 때 까지 2번부터 8번까지 반복하고 삭제 할 블록이 없으면 루프를 빠져 나오고 삭제한 블록의 개수를 return 한다.

결과

번호 속도
테스트 1 통과 (0.07ms, 52.3MB)
테스트 2 통과 (0.09ms, 51.7MB)
테스트 3 통과 (0.04ms, 51.9MB)
테스트 4 통과 (1.08ms, 52.5MB)
테스트 5 통과 (14.40ms, 52.6MB)
테스트 6 통과 (3.08ms, 52.3MB)
테스트 7 통과 (0.81ms, 52.3MB)
테스트 8 통과 (1.81ms, 53.7MB)
테스트 9 통과 (0.07ms, 53.4MB)
테스트 10 통과 (0.59ms, 51.7MB)
테스트 11 통과 (1.38ms, 52.7MB)

테스트 케이스

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
assertEquals(14, test.solution(4,5, new String[] {"CCBDE", "AAADE", "AAABF", "CCBBF"}));
assertEquals(15, test.solution(6,6, new String[] {"TTTANT", "RRFACC", "RRRFCC", "TRRRAA", "TTMMMF", "TMMTTJ"}));
assertEquals(14, test.solution(4,5, new String[] {"AAAAA","AUUUA","AUUAA","AAAAA"}));
assertEquals(4, test.solution(2,2, new String[] {"AA","AA"}));
assertEquals(0, test.solution(2,2, new String[] {"AA","AB"}));
assertEquals(4, test.solution(3,2, new String[] {"AA","AA", "AB"}));
assertEquals(8, test.solution(4,2, new String[] {"CC","AA", "AA", "CC"}));
assertEquals(12, test.solution(6,2, new String[] {"DD", "CC", "AA", "AA", "CC", "DD"}));
assertEquals(8, test.solution(8,2, new String[] {"FF", "AA", "CC", "AA", "AA", "CC", "DD", "FF"}));
assertEquals(8, test.solution(6,2, new String[] {"AA", "AA", "CC", "AA", "AA", "DD"}));
assertEquals(8, test.solution(4,4, new String[] {"ABCD", "BACE", "BCDD", "BCDD"}));
assertEquals(27, test.solution(8,9, new String[] {"ABCDADFDA", "ABDFQWERF", "WKDNFNRIT", "AKAKWODCJ", "AKAKWODCJ", "KKKKKKKKK", "KKKKKKKKK", "KKKKKKKKK"}));
assertEquals(15, test.solution(4,5, new String[] {"AAAAA", "AAAAU", "AAAUU", "UUUUU"}));
assertEquals(24, test.solution(5,6, new String[] {"AAAAAA", "BBAATB", "BBAATB", "JJJTAA", "JJJTAA"}));
assertEquals(32, test.solution(6,6, new String[] {"AABBEE", "AAAEEE", "VAAEEV", "AABBEE", "AACCEE", "VVCCEE"}));