본문 바로가기
Java/알고리즘

[Java] 프로그래머스 Lv2 - 2018 KAKAO BLIND RECRUITMENT[1차] 프렌즈4블록

by WaterPunch 2024. 12. 11.

 

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 

 

import java.util.*;

public class Solution {

    public int solution(int m, int n, String[] board) {
        // 컬럼별로 쌓인 블록을 저장하는 Map 생성
        // key : column 번호
        // ArrayList : 쌓인 블록
        HashMap<Integer, ArrayList<String>> stackedMap = new HashMap<>();

        // 맨 아래층부터 실행
        for(int row=m-1; row>=0; row--) {
            for(int column=0; column<n; column++) {
                ArrayList<String> list = stackedMap.getOrDefault(column, new ArrayList<String>());
                list.add(String.valueOf(board[row].charAt(column)));
                stackedMap.put(column, list);
            }
        }

        // 컬럼별로 가장 높은 Row의 수
        int topRow = 0;
        ArrayList<String> deleteBlockPoint;
        int answer = 0;

        // 제거할 블록이 없을때까지 반복
        while(true) {
            //해당 턴이 끝날때 일괄 삭제할 블록좌표를 들고 있을 ArrayList 생성
            deleteBlockPoint = new ArrayList<>();

            // 각 컬럼별로 가장 높은 곳을 찾는다
            for (ArrayList<String> columnBlocks : stackedMap.values()) {
                if(topRow < columnBlocks.size()) topRow = columnBlocks.size();
            }

            // 맨 아래층부터 왼쪽->오른쪽 순으로 제거할 블록을 찾는다
            for(int row=0; row<topRow-1; row++) {
                for(int column=0; column<n-1; column++) {
                    // 현재 컬럼에 쌓인 블록들 get
                    // 해당 컬럼에 쌓인게 없다던가, 현재 Row+1 의 블록이 없으면 패스
                    ArrayList<String> currentColumnStackedBlocks = stackedMap.get(column);
                    if(currentColumnStackedBlocks.isEmpty()) continue;
                    if(currentColumnStackedBlocks.size() <= row+1) continue;

                    // 현재 Row, Column의 블록을 get
                    // 현재 Row+1, Column의 블록을 get
                    // 두개의 블록이 같은지 확인
                    String currentBlock = currentColumnStackedBlocks.get(row);
                    String nextRowBlock = currentColumnStackedBlocks.get(row + 1);
                    if(!nextRowBlock.equals(currentBlock)) continue;

                    // 다음 컬럼에 쌓인 블록들 get
                    // 해당 컬럼에 쌓인게 없다던가, 현재 Row+1 의 블록이 없으면 패스
                    ArrayList<String> nextColumnStackedBlocks = stackedMap.get(column + 1);
                    if(nextColumnStackedBlocks.isEmpty()) continue;
                    if(nextColumnStackedBlocks.size() <= row+1) continue;

                    // 현재 Row, Column+1의 블록을 get
                    // 현재 Row, Column의 블록과 같은지 확인
                    String nextColumnBlock = nextColumnStackedBlocks.get(row);
                    if(!currentBlock.equals(nextColumnBlock)) continue;

                    // 현재 Row+1, Column+1의 블록을 get
                    // 현재 Row, Column+1의 블록과 같은지 확인
                    String nextColumnRowBlock = nextColumnStackedBlocks.get(row + 1);
                    if(!nextColumnBlock.equals(nextColumnRowBlock)) continue;

                    // 4개의 블록이 같을 경우 실행
                    // 해당 턴이 끝날때 일괄 삭제할 블록의 row list의 index, column key를 들고 있을 ArrayList 에 넣어준다
                    // 이미 삭제대상인 블록이라면 List에 넣어주지 않는다
                    // 정렬을 위해서 06/10 (6번 row/10번 컬럼) 과 같은 형태로 저장하고 있는다
                    String p1 = String.format("%02d", row) + "/" + String.format("%02d", column);
                    String p2 = String.format("%02d", row+1) + "/" + String.format("%02d", column);
                    String p3 = String.format("%02d", row) + "/" + String.format("%02d", column+1);
                    String p4 = String.format("%02d", row+1) + "/" + String.format("%02d", column+1);
                    if(!deleteBlockPoint.contains(p1)) deleteBlockPoint.add(p1);
                    if(!deleteBlockPoint.contains(p2)) deleteBlockPoint.add(p2);
                    if(!deleteBlockPoint.contains(p3)) deleteBlockPoint.add(p3);
                    if(!deleteBlockPoint.contains(p4)) deleteBlockPoint.add(p4);
                }
            }

            // 삭제할 블록이 없다면 while문 종료
            if(deleteBlockPoint.isEmpty()) break;
            // 큰 번호의 Row부터 지워주기 위해 내림차순 정렬
            Collections.sort(deleteBlockPoint);
            Collections.reverse(deleteBlockPoint);

            // 삭제블록 좌표 리스트를 통해 삭제
            for (String point : deleteBlockPoint) {
                String[] split = point.split("/");
                int row = Integer.parseInt(split[0]);
                int column = Integer.parseInt(split[1]);

                stackedMap.get(column).remove(row);
                answer++;
            }
        }
        return answer;
    }
}

 

반응형

댓글