알고리즘/프로그래머스

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

정석이 2021. 11. 24. 17:27

 

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

 

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

[[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

 

 

문제

 

 

 


 

내가 푼 코드

 

 

결론부터 말하자면 테스트케이스 1,2에서 실패했다. 참내..... 질문하기 들어가서 사람들이 말해준 테스트케이스를 다 해봤는데도 왜 안되는지 모르겠음ㅋ

 

 

 

틀린 코드

import java.util.ArrayList;

class Solution {
    public int solution(int[][] board, int[] moves) {
        int answer = 0;
        
        ArrayList <Integer> basket = new ArrayList<>();
        
        for(int i = 0; i < moves.length; i++){
            for(int j = 0; j < board.length; j++){ // 행 길이
                if(board[j][moves[i]-1] == 0) continue;
                else{
                    basket.add(board[j][moves[i]-1]);
                    board[j][moves[i]-1] = 0;
                    break;
                }
            }
        }
        
        int size = basket.size();
        
        for(int i = 0; i < basket.size()-1; i++){
            for(int j = 0; j < basket.size()-1; j++){
                if(basket.get(j) == basket.get(j+1)){
                    basket.remove(j);
                    basket.remove(j);
                    break;
                } else continue;
            }
        } // 바로 옆에 있는 겹치는거 없애기
        
        if(basket.size() == 2 && (basket.get(0) == basket.get(1))) // 2개 들어있을 때 위 for문이 돌지 않으므로 따로 써줌
                basket.clear();
        
        answer = size - basket.size();
        return answer;
    }
}

 

 

다시 말하지만 테스트케이스 1,2는 틀렸다.

 

내 생각엔 basket에 숫자를 넣는것까진 맞는데 거기서 pop되는걸 구현한게 틀린 것 같다.

 

이 부분이 오래걸리기도 했고....

 

 

저 j+1이 basket 사이즈끝에 닿으면 멈추게 하고싶었는데.... ㅎ~

 

 

 

 


 

 

남의 코드를 보면서 익혀야지!

 

 

 

https://zzang9ha.tistory.com/224

import java.util.Stack;

class Solution {
	public static int solution(int[][] board, int[] moves) {
		int answer = 0;
		Stack<Integer> s = new Stack<Integer>();
		for(int i=0; i<moves.length; i++) {
			for(int j=0; j<board.length; j++) {
				/* 
				 * 해당 칸에 인형이 존재하는경우
				 * ↓ 아래로 내려가므로 행의 값이 계속 바껴야함 (0,0), (1,0), (2,0) ...
				 * moves배열에 있는 요소를 board[][] 배열의 '열' 값에 넣어서 비교
				 * 배열의 인덱스는 0부터 시작하므로 -1
				 */ 
				if(board[j][moves[i]-1] != 0) {
					
					// 스택이 비어있는경우 -> 해당 인형 넣기
					if(s.isEmpty())
						s.push(board[j][moves[i]-1]);
					
					// 스택이 비어있지 않는경우 -> 인형이 동일한지 아닌지 비교
					else {
						// 인형이 동일하면 제거 후 사라진 인형개수 +2
						if(s.peek() == board[j][moves[i]-1]) {
							s.pop();
							answer += 2;
						}
						// 인형이 동일하지 않으면 스택에 인형 넣기
						else {
							s.push(board[j][moves[i]-1]);
						}
					}
					// 해당 작업 끝난 후에는 인형을 빼냈으므로 0으로 만든다.(인형이 없다는 표시)
					board[j][moves[i]-1] = 0;
					break;
				}
			}
		}
		return answer;
	}
}

 

 

stack을 사용해서 board 배열에 있는 값을 넣을 때마다 전 값과 비교해서 같으면 pop 시켜줬다.

 

stack()은 후입선출이다. 걍 바구니를 생각하면 쉽다. 최근에 넣은걸 꺼내게되고 점점 쌓이는 형태이다.

 

 

Stack<Element> stack = new Stack<>();

 

일케 선언한다.

 

사용할 수 있는 함수는

public Element push(Element item); // 데이터 추가
public Element pop(); // 최근에 추가된//가장 위에 있는(Top) 데이터 삭제
public Element peek(); // 최근에 추가된/가장 위에 있는(Top) 데이터 반환
public boolean empty(); // stack의 값이 비었는지 확인-> 비었으면 true, 아니면 false
public int seach(Object o); // 인자값으로 받은 데이터의 위치 반환

 

이 5가지이다.

 

 

스택을 사용했으면 이분꺼랑 비슷한 코드가 나왔을 것 같다.

 

 

 

 

 

 

 

위에꺼랑 비슷한데 for each문을 사용한 것만 다르다. 이게 정석이구나...

 

 

 

 

 

 

내가 구현하던 ArrayList와 아주 비슷하다.

 

중복 삭제 구현을

 

 

for(int k=0;k<nums.size();k++){
            if(k!=(nums.size()-1)){
                if(nums.get(k)==nums.get(k+1)){
                    nums.remove(k);
                    nums.remove(k);
                    answer++;
                    k=-1;
                }
            }
}

 

이렇게 하셨다.

 

k가 바구니사이즈 - 1에 도달하지 않았고 k번째랑 k+1번째가 같으면 삭제해주는......

 

 

그리고 같으면 k = -1로 해줘서 다시 k = 0부터 훑게 만든다. (for문 돌 때 +1이니까 k = -1이어야 k = 0이 된다)