오늘은 여기까지

[프로그래머스] 프렌즈4블록 (Lv.2) - 자바 Java 본문

Problem Solving

[프로그래머스] 프렌즈4블록 (Lv.2) - 자바 Java

dev-99 2024. 7. 3. 06:09

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

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr


0. board 문자열을 2차원 배열로 저장하는 부분

String[][] block = new String[board[0].length()][board[0].length()];
for (int i = 0; i < board.length; i++) {
	for (int j = 0; j < board[0].length(); j++) {
		block[i][j] = String.valueOf(board[i].charAt(j));
	}
}

1. 제거할 4블록을 확인하는 부분

boolean remove = false; // 제거할 블록 존재 여부
boolean[][] check = new boolean[m][n]; // 제거할 블록 저장
for (int i = 0; i < m; i++) {
	for (int j = 0; j < n; j++) {
		String a = block[i][j];
		String b = block[i][j + 1];
		String c = block[i + 1][j];
		String d = block[i + 1][j + 1];
		if (a.equals("-")) {
			continue;
		}
		if (a.equals(b) && b.equals(c) && c.equals(d)) {
			check[i][j] = true;
			check[i][j + 1] = true;
			check[i + 1][j] = true;
			check[i + 1][j + 1] = true;
			remove = true;
		}
	}
}

2. 제거할 4블록을 삭제하는 부분

// 제거할 블록이 있는 경우
for (int i = 0; i < m; i++) {
	for (int j = 0; j < n; j++) {
		if (check[i][j]) {
			block[i][j] = "-";
			answer++;
		}
	}
}

3. 블록 내리기

제일 안떠올랐던 부분인데, 처음 작성한 코드는 아래와 같다. 5번, 10번 테스트케이스에서 실패가 떴다.

// 블록 내리기
for (int i = 0; i < m; i++) {
	for (int j = 0; j < n; j++) {
		if (block[i][j].equals("-")) {
			for (int k = i - 1; k >= 0; k--) {
				if (!block[k][j].equals("-")) {
					String temp = block[i][j];
					block[i][j] = block[k][j];
					block[k][j] = temp;
					break;
				}
			}
		}
	}
}

 

위에서부터 훑다가 빈칸이 나오면 다시 해당 열을 거꾸로(위로) 훑으면서 빈칸이 아닌 블록을 만나면 내려주는 것이다.

에러를 모르겠어서 찾아보니 효율성 문제일 수도 있다고 하길래 아래서부터 훑도록 수정했고, 통과가 됐다. 코드는 다음과 같다.

// 블록 내리기
for (int i = m - 1; i > 0; i--) { // 수정한 부분
	for (int j = 0; j < n; j++) {
		if (block[i][j].equals("-")) {
			for (int k = i - 1; k >= 0; k--) {
				if (!block[k][j].equals("-")) {
					String temp = block[i][j];
					block[i][j] = block[k][j];
					block[k][j] = temp;
					break;
				}
			}
		}
	}
}

 

또 생각해보니 내려줄 블록은 항상 위에 있어서 아래서부터 탐색하는게 효율적인 것 같기도 하다


전체 코드

더보기
import java.util.Arrays;

class Solution {
    public int solution(int m, int n, String[] board) {
        int answer = 0;
        String[][] block = new String[m][n];
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                block[i][j] = String.valueOf(board[i].charAt(j));
            }
        }
        
        // for(String[] b : block) {
        //     System.out.println(Arrays.toString(b));
        // }
        
        // 블록이 더 이상 제거되지 않을때까지 반복
        while (true) {
            boolean remove = false; // 제거핧 블록 존재 여부
            boolean[][] check = new boolean[m][n]; // 제거할 블록 저장
            for (int i = 0; i < m - 1; i++) {
                for (int j = 0; j < n - 1; j++) {
                    String a = block[i][j];
                    String b = block[i][j + 1];
                    String c = block[i + 1][j];
                    String d = block[i + 1][j + 1];
                    if (a.equals("-")) {
                        continue;
                    }
                    if (a.equals(b) && b.equals(c) && c.equals(d)) {
                        check[i][j] = true;
                        check[i][j + 1] = true;
                        check[i + 1][j] = true;
                        check[i + 1][j + 1] = true;
                        remove = true;
                    }
                }
            }
            
            // 제거할 블록이 더 이상 없다면 종료
            if (!remove) {
                break;
            }
            
            // 제거할 블록이 있는 경우
            for (int i = 0; i < m; i++) {
                for (int j = 0; j < n; j++) {
                    if (check[i][j]) {
                        block[i][j] = "-";
                        answer++;
                    }
                }
            }
            
            // 블록 내리기
            for (int i = m - 1; i > 0; i--) {
                for (int j = 0; j < n; j++) {
                    if (block[i][j].equals("-")) {
                        for (int k = i - 1; k >= 0; k--) {
                            if (!block[k][j].equals("-")) {
                                String temp = block[i][j];
                                block[i][j] = block[k][j];
                                block[k][j] = temp;
                                break;
                            }
                        }
                    }
                }
            }
            // END OF FOR문
        }
        // END OF WHILE문
        
        return answer;
    }
}

이게 Lv.2 문제라니... ㅠ