- 문제설명
- 해결과정
좌표의 중복처리를 어떻게 할까?
현재 배열이 캐릭터 타입이고, 모두 대문자라는 점에서 힌트를 얻을 수 있었다.
2X2 한세트를 처리할 때 그냥 소문자로 바꿔주면 된다.
이렇게 되면, 소문자로 바꿨는데 주변은 대문자라서 같은 2X2 세트로 체크가 안될 수 있지 않을까? 라는 생각을 할 수 있지만
비교할 때 해당 문자를 임시로 대문자로 바꿔주고 비교하면 같은 무리인지는 충분히 판단할 수 있다.
이렇게 모든 2X2세트를 소문자로 바꿔주면, 전체 배열에서 소문자의 개수 = 터진 블럭의 수가 된다.
최초 String[] 배열로 주어진 입력을 char[][] 배열로 변형시켰기 때문에 가능한 풀이였다.
다음은 최종 풀이 방식이다.
이렇게 총 4개의 메소드를 만들었다.
메인문에서는 아래와 같이 작성해주면 답을 구할 수 있다.
public int solution(int m, int n, String[] board) {
.
.
.
while(canNext()) {
changeToLower();
sumAndLowerToX();
moveToDown();
}
return sum;
}
- 솔루션
import java.util.*;
class Solution {
private static char[][] coordinate;
private static int N, M, sum;
public int solution(int m, int n, String[] board) {
coordinate = new char[m][n];
N = m; // N은 가로길이
M = n; // M은 세로길이
sum = 0;
for(int i = 0; i < N; i++) {
for(int j = 0; j < M; j++) {
coordinate[i][j] = board[i].charAt(j);
}
}
// 캐릭터 배열로 변환!
while(canNext()) {
changeToLower();
sumAndLowerToX();
moveToDown();
}
return sum;
}
private static boolean canNext() {
for(int i = 0; i < N - 1; i++) {
for(int j = 0; j < M - 1; j++) {
char who = coordinate[i][j];
if(who != 'X' && coordinate[i][j+1] == who && coordinate[i+1][j] == who && coordinate[i+1][j+1] == who) {
return true;
}
}
}
return false;
}
private static void changeToLower() {
for(int i = 0; i < N - 1; i++) {
for(int j = 0; j < M - 1; j++) {
if(coordinate[i][j] == 'X') continue;
char who = Character.toUpperCase(coordinate[i][j]);
if(Character.toUpperCase(coordinate[i][j+1]) == who &&
Character.toUpperCase(coordinate[i+1][j]) == who &&
Character.toUpperCase(coordinate[i+1][j+1]) == who) {
coordinate[i][j] = Character.toLowerCase(coordinate[i][j]);
coordinate[i][j+1] = Character.toLowerCase(coordinate[i][j+1]);
coordinate[i+1][j] = Character.toLowerCase(coordinate[i+1][j]);
coordinate[i+1][j+1] = Character.toLowerCase(coordinate[i+1][j+1]);
}
}
}
}
private static void sumAndLowerToX() {
for(int i = 0; i < N; i++) {
for(int j = 0; j < M; j++) {
if(Character.isLowerCase(coordinate[i][j])) {
sum++;
coordinate[i][j] = 'X';
}
}
}
}
private static void moveToDown() {
for(int i = 0; i < M; i++) {
for(int j = N - 2; j >= 0; j--) {
if(coordinate[j][i] != 'X') {
char temp = coordinate[j][i];
coordinate[j][i] = 'X';
int currentY = j;
while(currentY+1 <= N-1 && coordinate[currentY+1][i] == 'X') {
currentY++;
}
coordinate[currentY][i] = temp;
}
}
}
}
}
- 배운점
처음에 좌표값의 중복을 없애고 보관하기 위해서 HashMap을 사용했다.
하지만 HashMap 내부의 데이터를 참조형으로 만들면, 실제로 같은 데이터를 가져도 주소가 다르기때문에 다른 데이터로 인식한다.
따라서 중복처리를 해주지 못한다.
단순한 int, char 같은 기본타입에만 적용된다는 사실을 잊지말자!
참고로 hashCode(), equals() 메소드를 오버라이딩해서 내부적으로 값만 같으면 같은 데이터로 인식하게끔 바꿀 순 있지만,
현재 문제에서 이 방식을 원하진 않는 것으로 판단됐다.
'코딩테스트 > 프로그래머스' 카테고리의 다른 글
[Java] 프로그래머스 Level 2 : 뉴스 클러스터링 (0) | 2023.08.10 |
---|---|
[Java] 프로그래머스 Level 2 : 땅따먹기 (0) | 2023.08.08 |
[Java] 프로그래머스 Level 1 : 크레인 인형뽑기 게임 (0) | 2023.07.20 |
[Java] 프로그래머스 Level 3 : 여행경로 (0) | 2023.07.10 |
[Java] 프로그래머스 Level 3 : 네트워크 (0) | 2023.07.09 |