문제 풀이 (JAVA)
import java.util.*;
public class part5_3 {
public static void main(String[] args) {
// 크레인 인형뽑기(카카오)
Scanner input = new Scanner(System.in);
int N = input.nextInt();
int [][] a = new int[N][N];
for(int i=0; i<N; i++) {
for(int j=0; j<N; j++) {
a[i][j]=input.nextInt();
}
}
int K = input.nextInt();
int [] b = new int[K];
for(int i=0; i<K; i++) {
b[i]=input.nextInt();
}
int answer = solution(a,N,b,K);
System.out.print(answer);
}
private static int solution(int [][] a, int N, int [] b, int K) {
int result = 0;
Stack<Integer> stack = new Stack<>(); // 스택선언
int idx=0; // 탐색할 배열 인덱스
for(int i=0; i<K; i++) { // b의 K번째까지 반복 탐색
idx=0; // 배열 인덱스 초기화
// 2차원 행렬 b번째 행렬에 a의 0번째 행부터 인덱스로 순차적으로 탐색하여 0이 아닐때까지 탐색
while(idx < N && a[idx][b[i]-1] == 0) {
idx++;
}
if(idx == N) { // 인덱스가 N까지 증가되었다면 b번째 행렬은 모두 0이므로 다음 for문 처리
continue;
}
// 스택에 값이 들어있다면
if(stack.size() != 0) {
if(a[idx][b[i]-1] == stack.peek()) { // 스택의 마지막 값과 현재 뽑은 a의 숫자가 같을 경우
stack.pop(); // 스택에서 값을 제거
result+=2; // 현재 뽑은 a를 추가하지 않고 결과값 +2
}else { // 마지막 스택 값과 다르다면 값 추가
stack.push(a[idx][b[i]-1]);
}
}else { // 스택이 비어있다면 값 추가
stack.push(a[idx][b[i]-1]);
}
a[idx][b[i]-1] = 0; // 뽑은 a의 행렬 값 0으로 초기화
}
return result;
}
}
주요 핵심 포인트
1. 이차원행렬의 인덱스를 머리에 잘 그려놓고 입력받은 b의 인덱스 값을 이용하여 값이 존재하는지 유무를 잘 판별해야한다.
2. 값을 추가 시켜주는 일차원 배열을 스택으로 구현하여, 스택의 마지막 값과 현재 값이 같다면 현재 값은 스택에 넣지 않고, 스택의 마지막값은 제거시킴으로써 result 값은 +2를 해주었다.
3. 스택이 존재하지 않을때의 처리를 잘해주어야 하고, 인덱스가 N까지 왔다면 모든 숫자가 0임으로 continue 처리를 해주었다.
개선해야할 사항
1. 실은 이 문제를 프로그래머스에서 스택의 개념을 모를때 한번 푼적이 있다. 그때 당시에 시간이 훨씬 오래 걸려서 간신히 풀었는데, 스택을 사용함으로써 다시 문제를 푼 결과 코드가 개선이 되었다고 생각한다. 아래는 이전에 풀었던 프로그래머스 코드이다.
프로그래머스 - 이전 소스 코드
import java.util.*;
class Solution {
public int solution(int[][] board, int[] moves) {
int answer = 0;
List<Integer> list = new ArrayList<Integer>();
for(int i=0; i<moves.length; i++){
int w=0;
int h=moves[i]-1;
if(list.size()>1){
// 리스트의 사이즈가 2개이상이고 마지막 값과 마지막 전 값이 같다면
while(list.get(list.size()-2)==list.get(list.size()-1)){
list.remove(list.size()-1); //마지막 값 제거
list.remove(list.size()-1); //제거된 리스트의 마지막 값 제거
answer+=2; // 결과 +2
if(list.size()<2){ // 사이즈 오류 방지--크기가 2보다 작다면 멈춰라.
break;
}
}
}
while(board[w][h] ==0){ // 값이 0이라면 찾을 행 증가
w++;
if(w==board.length-1){ // 마지막 행도 0이라면 반복 증가 멈춰라.
break;
}
}
if(w==board.length-1 && board[w][h]==0){ // 마지막이 0이라면 스킵
continue;
}
if(board[w][h] != -1){ // 0이 아니라면 값이 있으므로
list.add(board[w][h]);
System.out.println(list);
board[w][h]=-1; // 값 저장 후 -1로 변환 후 스킵
continue;
}
if(board[w][h] == -1){ // -1은 사용된 값으로 -1이 나온다면
while(board[w][h] == -1){ // -1이 아닐때까지 반복 증가
w++;
if(w==board.length){ // 다음 행이 마지막 행이라면 멈춰라.
break;
}
if(board[w][h] != -1){ // 마지막행이 아니라면 뽑아야 될 값
list.add(board[w][h]);
board[w][h]=-1; // 리스트 저장 후 스킵
break;
}
}
}
}
return answer;
}
}
이때는 리스트의 개념만 알고 있어 힘들게 풀었다. 스택의 개념을 공부하고 풀어 보니, 이전에 풀었던 코드의 1/2 라인 수로 쉽게 풀 수 있었다. 알고리즘을 공부하는 이유를 오늘에서 좀 더 체감하고 간다. 앞으로도 더 성장하자.
'알고리즘' 카테고리의 다른 글
[스택] 쇠막대기 (인프런 알고리즘 5-5) (0) | 2022.06.26 |
---|---|
[스택] 후위식 연산(postfix) (인프런 알고리즘 5-4) (0) | 2022.06.20 |
[스택] 괄호문자제거 (인프런 알고리즘 5-2) (0) | 2022.06.19 |
[스택] 올바른 괄호 (인프런 알고리즘 5-1) (0) | 2022.06.19 |
[트리셋(TreeSet)] K번째 큰 수 (인프런 알고리즘 4-5) (0) | 2022.06.19 |