(Java) 프로그래머스 76502. 괄호 회전하기

최권민·2023년 7월 26일
0

알고리즘 풀이

목록 보기
11/13
post-thumbnail

문제

다음 규칙을 지키는 문자열을 올바른 괄호 문자열이라고 정의합니다.

(), [], {} 는 모두 올바른 괄호 문자열입니다.
만약 A가 올바른 괄호 문자열이라면, (A), [A], {A} 도 올바른 괄호 문자열입니다. 예를 들어, [] 가 올바른 괄호 문자열이므로, ([]) 도 올바른 괄호 문자열입니다.
만약 A, B가 올바른 괄호 문자열이라면, AB 도 올바른 괄호 문자열입니다. 예를 들어, {} 와 ([]) 가 올바른 괄호 문자열이므로, {}([]) 도 올바른 괄호 문자열입니다.
대괄호, 중괄호, 그리고 소괄호로 이루어진 문자열 s가 매개변수로 주어집니다. 이 s를 왼쪽으로 x (0 ≤ x < (s의 길이)) 칸만큼 회전시켰을 때 s가 올바른 괄호 문자열이 되게 하는 x의 개수를 return 하도록 solution 함수를 완성해주세요.
상세보기


  • 문자열을 다루는 문제인데, JAVA에서 잘 안썼던 다른 자료구조들도 써보고 싶었음
  • if문을 많이 사용해도 되지만, 최대한 안 쓰는 방향으로 진행
  • 아직까지 자료구조의 초기화에 어려움이 있고, 메서드도 헷갈리는 게 많아 좀 더 연습해야 할 듯
import java.util.*;


class Solve1 {

	private final Map<Character, Character> brackets = new HashMap<>() {{
		put(']','[');
		put('}','{');
		put(')','(');
	}};

	private Deque<Character> rotate(Deque<Character> que){

		Character a = que.pollFirst();
		que.add(a);

		return que;
	}

	private int checkPairs(Deque<Character> que){
		Deque<Character> bracketList = new ArrayDeque<>();
		bracketList.add('A');
		for (Character c : que) {
			if(c == '{' || c == '[' || c == '('){
				bracketList.add(c);
			}
			else{
				Character x = bracketList.pollLast();
				if(!x.equals(brackets.get(c))){
					return 0;
				}
			}
		}
		if(bracketList.size() > 1){
			return 0;
		}

		return 1;
	}

	public int solution(String s) {
		int answer = 0;

		Deque<Character> bracketQue = new ArrayDeque<>();
		for (char c : s.toCharArray()) {
			bracketQue.add(c);
		}
		for (int i = 0; i < s.length(); i++) {
			answer += checkPairs(bracketQue);
			bracketQue = rotate(bracketQue);
		}

		return answer;
	}

}

문제 해설

  • 두 가지의 과정이 필요한 문제
  1. 왼쪽으로 한 칸 돌리기
    • 아무래도 List를 쓰는 것보다는 Deque를 쓰는 게 시간복잡도 상 효율적이라고 생각해서 Deque 를 사용
    • 파이썬 같은 경우에는 Deque에 기본적으로 rotate 함수가 내장되어 있어, 따로 구현하지 않아도 되었지만 Java에는 없는 듯 하여 추가
  2. 괄호의 쌍이 맞는 지 판별하기
    • 여는 괄호면 따로 List에 담고, 닫는 괄호면 List의 마지막 값을 가져와서 쌍이 맞는 지 확인하도록 로직을 구현
    • if문으로 해도 되지만, Map을 써서 판별하면 좀 더 깔끔하고 가독성 있는 코드가 될 거라고 생각했음
    • 마지막까지 순회한 후, List의 사이즈를 확인하여 남은 게 있으면 false를 반환하도록 함
  • Python의 경우, true와 false를 int처럼 연산할 수 있지만, 자바는 불가능하여 return값을 0 or 1 로 설정하도록 함

❗ 오답노트

  1. contains에 따른 오답
    • 처음에는 여는 괄호를 현재처럼 ||로 확인하는 게 아니라, 리스트를 만들어 놓고 contains로 확인하려고 했음
    • 아무래도 Character 자료형에서는 contains 비교가 불가능한 듯 하여, ||로 비교하도록 수정
  2. Deque에서 pop() 메서드를 사용
    • pop() 같은 경우는, 파이썬에서는 마지막 값을 꺼내는 메서드이지만 Java의 Deque에서는 첫번째 값을 꺼내는 메서드기 때문에 오류가 발생
    • padding의 의미로 'A'를 넣어두었지만, 예외를 발생시키기는 싫어서 removeLast 대신 pollLast를 사용
profile
하나의 궤적을 따라서

0개의 댓글