하루에 한 문제

[프로그래머스-lv2 2018 KAKAO BLIND RECRUITMENT] 프렌즈 4블록 -Java 본문

알고리즘/프로그래머스 lv2 다시풀기

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

dkwjdi 2021. 3. 15. 00:17

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

 

코딩테스트 연습 - [1차] 프렌즈4블록

프렌즈4블록 블라인드 공채를 통과한 신입 사원 라이언은 신규 게임 개발 업무를 맡게 되었다. 이번에 출시할 게임 제목은 "프렌즈4블록". 같은 모양의 카카오프렌즈 블록이 2×2 형태로 4개가 붙

programmers.co.kr

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
class Solution {
	    public int solution(int m, int n, String[] board) {
	        int answer = 0;
	        int dx[]= {0,1,1}; // 오른쪽, 오른쪽아래 대각선, 아래
	        int dy[]= {1,1,0};
	        
	        char boards[][]=new char[m][n];
	        for(int i=0; i<m; i++) {
	        	boards[i]=board[i].toCharArray();
	        }
	        
	        while(true) {
	        	List<int[]> removePoint= new ArrayList<>();
	        	remove(boards,dx,dy,removePoint,m,n);
	        	if(removePoint.size()==0) break;
	        	answer+=removeExe(boards,removePoint,dx,dy);
	        	down(boards,m,n);
	        }
	        
	        
	        return answer;
	    }

		private void down(char[][] boards,int m, int n) {
			for(int j=0; j<n; j++) {
				Queue <Character> queue =new LinkedList<>();
				for(int i=m-1; i>=0; i--) {
					if(boards[i][j]=='0') continue;
					queue.add(boards[i][j]);
				}
				
				for(int ii=m-1; ii>=0; ii--) {
					if(queue.isEmpty()) boards[ii][j]='0'; //비었으면
					else boards[ii][j]=queue.poll();
					
				}
				
			}
			
		}

		private int removeExe(char[][] boards, List<int[]> removePoint, int[] dx, int[] dy) {
			int sum=0;
			for(int i=0; i<removePoint.size(); i++) {
				int point[]=removePoint.get(i); //삭제할 좌표
				if(boards[point[0]][point[1]]!='0') {
					sum++;
					boards[point[0]][point[1]]='0';
				}
				for(int d=0; d<3; d++) {
					int nx=point[0]+dx[d];
					int ny=point[1]+dy[d];
					
					if(boards[nx][ny]!='0') {
						sum++;
						boards[nx][ny]='0';
					}
				}
				
			}
			return sum;
		}

		private void remove(char[][] boards, int[] dx, int[] dy, List<int[]> removePoint, int m, int n) {
			for(int i=0; i<m-1; i++) {
				for(int j=0; j<n-1; j++) {
					int cnt=0; //몇개 같은지
					char ch=boards[i][j];
					if(ch=='0') continue;
					for(int d=0; d<3; d++) {
						int nx=i+dx[d];
						int ny=j+dy[d];
						
						if(boards[nx][ny]==ch) cnt++;
						else break;
					}
					
					if(cnt==3) removePoint.add(new int[] {i,j});
					
				}
			}
			
		}
	}

소요시간 : 28분

 

우선 저는 String배열로 들어온  board를 char 2차원배열인 boards로 바꿔서 풀었습니다! 

그리고 맨왼쪽부터 맨아래까지 순회를 하면서 자신위치 기준 오른쪽, 오른쪽아래, 아래가 똑같다면 

리스트에 자신의 위치를 저장하고 나중에 그것을 통해 삭제해줬습니다~

 

만약 리스트에 아무것도 안들어있다면 삭제할 수 있는게 없다는 뜻이니까 while문 탈출하시면 됩니다!

 

우선 로직을 살펴보면

 

1. String배열을 2차원 char배열로 바꿔준다.

2. 지워야 하는 좌표의 왼쪽위 좌표를 저장한다.

3. 2번에서 구한 좌표를 기준으로 boards배열값을 삭제해준다.

4. queue를 이용해서 아래로 내린다.

 

끝~

Comments