문제 풀이 (JAVA)

import java.util.*;
public class part5_5 {

	public static void main(String[] args) {
		// 쇠막대기
		Scanner input = new Scanner(System.in);
		
		String str = input.nextLine();
		int answer = solution(str);
		System.out.print(answer);
		
	}
	private static int solution(String s) {
		int result=0;
		Stack<Character> stack = new Stack<>();
		char [] ch = s.toCharArray();
		for(int i=0; i<ch.length; i++) {
			if(ch[i] == '(') {
				stack.push(ch[i]);
			}else if(ch[i]==')') {
				stack.pop();
				if(ch[i-1] == '(') { // 레이저일경우
					result += stack.size(); // 스택의 사이즈만큼 증가
				}else { // 레이저가 아닐경우(막대의종료)
					result ++; // 막대의 끝으로 +1 증가
				}
			}
		}
		return result;
	}
}

주요 핵심 포인트

1. 여는 괄호 '('를 만날시 스택에 추가한다.

2-1. 닫는괄호 ')'를 만날시 현재 인덱스 -1번째 문자가 여는괄호라면 스택에서 제거하고 결과값을 1 추가한다.

2-2. 닫는괄호 ')'의 현재 인덱스 -1번째 문자가  '(' 여는괄호가 아니라면 막대기의 종료로써 스택에서 제거하고 남아있는 스택의 개수만큼 결과값에 추가한다.

 

개선해야할 사항

1. 처음 문제를 이해하지 못하여 2-1의 케이스를 생각하지 못하였다. 막대기가 종료될때에는 +1을 추가해주면 된다는 것을 인지하자.

문제 풀이 (JAVA)

import java.util.*;
public class part5_4 {

	public static void main(String[] args) {
		// 후위식 연산(postfix)
		Scanner input = new Scanner(System.in);
		
		String a = input.nextLine();
		int answer = solution(a);
		System.out.print(answer);
	}
	private static int solution(String a) {
		int result=0;
		Stack<Integer> stack = new Stack<>();
		int sum=0;
		int num1=0 , num2=0;
		for(Character ch : a.toCharArray()) {
			if(Character.isDigit(ch) == true) {
				stack.push(Character.getNumericValue(ch));
			}else {
				if(ch == '+') {
					num1= stack.pop(); 
					num2= stack.pop();
					sum =(num2 + num1);
					stack.push(sum);
				}else if(ch == '-') {
					num1= stack.pop();
					num2= stack.pop();
					sum =(num2 - num1);
					stack.push(sum);
				}else if(ch == '*') {
					num1= stack.pop();
					num2= stack.pop();
					sum =(num2 * num1);
					stack.push(sum);
				}else if(ch == '/') {
					num1= stack.pop();
					num2= stack.pop();
					sum =(num2 / num1);
					stack.push(sum);
				}
			}
		}
		result = stack.pop();		
		return result;
	}
}

주요 핵심 포인트

1. 숫자를 만날 시 스택에 추가한다.

2. 연산식을 만날 시 스택에서 두 개의 값을 추출하여 해당 연산자로 연산 후 다시 스택에 넣는다.

3. 1-2번을 반복한다.

 

개선해야할 사항

1. 후위식을 스택으로 풀 수 있을 줄은 몰랐다. 후위식이 어떻게 이루어져 있는지 다시 한번 개념을 찾아 보고 나서 풀 수 있었던 문제이다. 다음부터는 후위식의 풀이식을 자연스럽게 생각하도록 해보자.

문제 풀이 (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 라인 수로 쉽게 풀 수 있었다. 알고리즘을 공부하는 이유를 오늘에서 좀 더 체감하고 간다. 앞으로도 더 성장하자.

문제 풀이 (JAVA)

import java.util.*;
public class part5_1 {

	public static void main(String[] args) {
		// 올바른 괄호
		Scanner input = new Scanner(System.in);
		
		String str = input.nextLine();
		
		String answer = solution(str);
		System.out.print(answer);

	}
	private static String solution(String str) {
		String result="YES";
		
		Stack<Character> stack = new Stack<>();
		
		for(Character ch : str.toCharArray()) {
			if(ch=='(') {
				stack.push(ch);
			}else if(ch==')') {
				// 스택에 값이 없을때를 처리한다.(처리 안할시 런타임오류)
				if(stack.isEmpty()==true) {
					result="NO";
					break;
				}
				stack.pop();
			}
		}
		// 최종적으로 처리했으나 값이 남아있다면 괄호가 맞지 않음
		if( stack.isEmpty() != true) {
			result="NO";
		}			
		return result;
	}
}

주요 핵심 포인트

1. 괄호 문제가 스택의 가장 기초적인 문제라고 한다. '(' 이 들어올시 stack에 넣고 ')'가 들어올시 스택에서 제거한다. 이를 이용하여 응용할시 쌍의 개수를 찾는 다른 문제 또한 적용하면 좋겠다.

2.  pop()을 할때 '(' 가 없을수도 있으므로 스택에 값이 없을시 런타임에러가 나므로 주의해주어야 한다.

3. 최종적으로 처리하여 스택이 남아있다는 것은 '(' 의 개수가 더 많은 것이므로 올바른 괄호가 아니다. 

개선해야할 사항

1.  스택 함수 선언 및 사용 방법을 런타임 에러가 나지 않도록 주의해서 코딩해야겠다.

+ Recent posts