본문 바로가기

ALGORITHM

[프로그래머스 Java] 크레인 인형뽑기 게임

 

코딩테스트 연습 - 크레인 인형뽑기 게임

[[0,0,0,0,0],[0,0,1,0,3],[0,2,5,0,1],[4,2,4,4,2],[3,5,1,3,1]] [1,5,3,5,1,2,1,4] 4

programmers.co.kr

⏱소요 시간 - 2시간

 

🔑문제 해결

 

인형 뽑기를 해서 배열에 넣고 중복을 제거할 때 다시 배열을 리스트로 변환하는 짓을 했다.

그래서인지 로직은 맞는데 테스트 케이스 1, 2번이 틀렸다고 했다.

애초에 배열에 넣지 않고 리스트에 넣고 시작을 하니 같은 로직으로 정답을 얻어냈다.

이게 뭐라고 두 시간이나 걸렸다^^

나중에 또 풀 때 수식 부분이 이해가 가지 않으면 이차원 배열의 인덱스를 그려서 생각해보면 바로 답이 나올 것이다!

 

🔎나의 소스 코드

 

package step1;

import java.util.ArrayList;

public class Ex01 {

	public static void main(String[] args) {

		int[][] board = { { 0, 0, 0, 0, 0 }, 
				  { 0, 0, 1, 0, 3 }, 
				  { 0, 2, 5, 0, 1 }, 
				  { 4, 2, 4, 4, 2 },
				  { 3, 5, 1, 3, 1 } };

		int[] moves = { 1, 5, 3, 5, 1, 2, 1, 4 };

		System.out.println(solution(board, moves));

	}

	public static int solution(int[][] board, int[] moves) {

		int answer = 0;
		
		ArrayList<Integer> list = new ArrayList<>(); // 인형을 담을 리스트

		for (int i = 0; i < moves.length; i++) { // 움직임 배열을 돌자 1, 5, 3, 5, ...

			for (int j = 0; j < board.length; j++) { // 보드판을 돌자

				if (!(board[j][moves[i] - 1] == 0)) { // 돌다가 0이 아닌 수를 만나면
					list.add(board[j][moves[i] - 1]); // 그 수를 리스트에 저장하자
					board[j][moves[i] - 1] = 0; // 그리고 뽑은 인형은 0으로 만들자
					break; // #1 이제 멈추고 다음 moves로 이동하자
				}

			}
		}

		for (int i = 0; i < list.size() - 1; i++) {

			if (list.get(i) == list.get(i + 1)) { // i번째 수와 그 다음 수가 같으면
	
				list.remove(i); // i번째 수 제거
				list.remove(i); // 이미 i번째 수를 제거했기 때문에 i+1이 아닌 i를 또 제거
				answer = answer + 2; // 두 개의 수를 제거하므로 +2
				
				i = -1; 
				// i = 0으로 하여 에러가 났었다.
				// -1로 해야 for문을 돌 때, i++을 거쳐 0으로 들어가기 때문에, -1로 해줘야함.
				// i를 0으로 초기화해버리면, i++을 거쳐서 i = 1부터 다시 돌게 됨.

			}

		}

		return answer;

	}

}

 

 

🔎스택을 이용한 풀이

 

해당 문제는 스택을 이용한 풀이가 더 많았다. 스택의 메서드에 익숙해지자.

 

isEmpty() : 스택이 비어있는지 확인

push() : 객체를 저장

peek() : 맨 위에 저장된 객체를 반환. 스택에서 꺼내지는 않음. 따라서 비교할 때 주로 사용!

pop() : 맨 위에 저장된 객체를 꺼냄

 

package step1;

import java.util.Stack;

// 크레인 인형뽑기 - 스택
public class Ex01_1 {

	public static void main(String[] args) {

		int[][] board = { { 0, 0, 0, 0, 0 }, 
				  { 0, 0, 1, 0, 3 }, 
				  { 0, 2, 5, 0, 1 }, 
				  { 4, 2, 4, 4, 2 },
				  { 3, 5, 1, 3, 1 } };

		int[] moves = { 1, 5, 3, 5, 1, 2, 1, 4 };

		System.out.println(solution(board, moves));

	}

	public static int solution(int[][] board, int[] moves) {

		int answer = 0;
		
		Stack<Integer> stack = new Stack<>(); // 인형을 담을 스택

		for(int i = 0; i < moves.length; i++) {
			
			for(int j = 0; j < board.length; j++) {
				
				int n = board[j][moves[i] - 1]; // 뽑은 인형
				
				if(n != 0) { // 인형이 뽑히면
					
					// 스택이 비어 있다면 여기로 (첫 번째 경우는 무조건 인형을 넣는다)
					if(stack.isEmpty()) {
						stack.push(n);
						board[j][moves[i] - 1] = 0;
						break;
					}
					
					// 스택이 비어있지 않다면 여기로
					if(stack.peek() == n) { // 스택 맨 위의 숫자가 방금 뽑은 것과 같은지 확인만!
						stack.pop(); // 같으면 제거 (새로운건 아직 추가도 안했으니 하나만 제거해도 OK)
						answer = answer + 2;
					} else { // 같지 않으면
						stack.push(n); // 추가
					}
					
					// if, else 로직 모두 해당되어야 하므로 괄호 밖으로 빼기
					board[j][moves[i] - 1] = 0;
					break;
					
				}
			}
		}
		
		return answer;

	}

}