hoon's bLog

Java 프로그래머스 괄호 회전하기 자바 본문

코딩테스트/프로그래머스

Java 프로그래머스 괄호 회전하기 자바

개발한기발자 2024. 3. 1. 08:36
반응형

 

문제출처 : https://school.programmers.co.kr/learn/courses/30/lessons/76502

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr


[문제]

[문제 풀기 전 생각/정리]

  • 문제는 회전이라고 표현했는데 설명에서는 왼쪽으로 이동하고 맨 첫 번째에 있었던 괄호는 오른쪽 끝으로 이동한다.
  • 이동하는 모습을 보고 Stack을 사용해야 겠다는 생각이 들었다!!
  • 특별히 규칙이 없어 보여 switch-case 문으로 괄호별 case를 구분해야겠다!

[나의 풀이]

import java.util.Stack;
class Solution {
    public int solution(String s) {
        int answer = 0;
        for (int i = 0; i < s.length(); i++) {
            if (isAnswer(s)) {
                answer++;
            }
            s = String.format("%s%s", s.substring(1), s.charAt(0));
        }
        return answer;
    }

    private boolean isAnswer(String s) {
        Stack<Character> stack = new Stack<>();
        for (char c : s.toCharArray()) {
            switch (c) {
                case '[': 
                case '{': 
                case '(': 
                    stack.push(c);
                    break;
                case ']': 
                    if (!isValid(stack, '[')) return false;
                    break;
                case '}': 
                    if (!isValid(stack, '{')) return false;
                    break;
                case ')': 
                    if (!isValid(stack, '(')) return false;
                    break;
            }
        }
        return stack.isEmpty();
    }

    private boolean isValid(Stack<Character> stack, char brk) {
        if (!stack.isEmpty() && stack.peek() == brk) {
            stack.pop();
            return true;
        }
        return false;
    }
}
  • solution(String s) : isAnswer 메서드를 호출하여 유효한 괄호열인지 확인 후, 회전시키기 위해 s 문자열의 첫 번째 문자를 마지막으로 이동시킨다.
  • isAnswer(String s) : Stack을 사용하여 괄호열을 검사하여, 여는 괄호인 경우 Stack에 push, 닫는 괄호인 경우 Stack에서 매칭되는 여는 괄호를 확인하여 isValid 메서드를 호출하여 유효성을 판단한다.
  • isValid(Stack<Character>, char brk) : Stack의 맨 위에 있는 괄호가 해당하는 여는 괄호인지 확인하고, 맞다면 스택에서 해당 괄호를 pop 해서 제거, Stack이 비어있는 경우나 맨 위의 괄호가 매칭되지 않는 경우 false를 반환한다.

설마 이 문제도 Stream을??...

혹시나 해서 다른 사람들의 풀이를 보았다.

import java.util.Stack;

class Solution {
    private final Stack<Character> stack = new Stack<>();

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

            for (int i = 0; i < s.length(); i++) {
                stringBuilder.append(stringBuilder.charAt(0));
                stringBuilder.deleteCharAt(0);
                if (correctParenthesis(stringBuilder.toString().toCharArray()))
                    answer++;
            }
            return answer;
        }

        private boolean correctParenthesis(char[] s) {
            for (char c : s) {
                if (!(check(c, '(', ')') && check(c, '[', ']') && check(c, '{', '}')))
                    return false;
            }
            return stack.isEmpty();
        }

        private boolean check(char c, char a, char b) {
            if (c == a)
                stack.push(a);
            else if (c == b)
                if (!stack.isEmpty() && stack.peek() == a) stack.pop(); else return false;
            return true;
        }
}
  • 다행히(?) 없었던 것 같다.
  • 문자열의 각 문자를 순회하면서 괄호열의 유효성을 확인 후, 괄호가 여는 괄호인 경우 Stack에 push, 괄호가 닫는 괄호인 경우 스택에서 매칭되는 여는 괄호를 확인하여 유효성을 판단하는 측면에서는 기능적으로 유사하다.

[정리]

개인 피셜 난이도 : ★

다만, 내 방식의 코딩은 기존에 문자열을 회전시키려면,

문자열을 잘라서 회전된 부분을 추출하고,

회전되지 않은 부분을 뒤에 붙이는 등의 작업으로 인해,

문자열을 재구성하는 작업이 비효율적이었다.

 

그러나 StringBuilder를 사용하면,

기존 문자열을 직접 수정하여 회전시킬 수 있어,

메모리 사용량과 실행 속도 면에서 효율적이다.

 

문제를 풀었다고 해서 끝나는 것이 아닌,

다른 사람의 코드와 비교해 보니,

아직도 부족함을 많이 느낀다.

 

뭐 별 수 없다.

이렇게라도 배워야지.

언제나 새로운 정보 공유, 잘못된 정보

지적/태클은 환영입니다!

도움이 되셨다면 공감♥️, 댓글 부탁드려요:)

끝.

728x90
반응형