250x250
250x250
JinSeopKim
Hello World!
JinSeopKim
전체 방문자
오늘
어제
  • 분류 전체보기 (168)
    • Artificial intelligence (14)
      • DeepDiveToAI (3)
      • Pytorch (3)
      • Etc (8)
    • Back-end (19)
      • Spring (10)
      • JPA (9)
    • Language (24)
      • Python (3)
      • Java (11)
      • Swift (10)
    • Math (4)
      • Linear Algebra (4)
    • CodingTest (79)
      • Algolithm (12)
      • Backjoon (25)
      • Programmers (42)
    • Etc (27)
      • Book Review (3)
      • Adsp (6)
      • Life (2)
      • Docker (1)
      • odds and ends (15)

블로그 메뉴

  • 홈
  • 태그
  • 방명록
  • GitHub

인기 글

태그

  • Python
  • 프로그래머스
  • BFS
  • 카카오
  • java
  • 자바
  • 머신러닝
  • DP
  • 구현
  • JAVA8
  • data
  • 개발자
  • 선형대수
  • BOJ
  • 백준
  • 개발
  • ios
  • 문제풀이
  • 파이썬
  • 알고리즘
  • certificate
  • 코딩테스트
  • AI
  • swift
  • uArm
  • ADsP
  • 브루트포스
  • JPA
  • Front-end
  • SpringMVC

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
JinSeopKim

Hello World!

[PGM_60058] 괄호 변환 (java)
CodingTest/Programmers

[PGM_60058] 괄호 변환 (java)

2022. 2. 7. 20:41
728x90
728x90

문제링크

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

 

코딩테스트 연습 - 괄호 변환

카카오에 신입 개발자로 입사한 "콘"은 선배 개발자로부터 개발역량 강화를 위해 다른 개발자가 작성한 소스 코드를 분석하여 문제점을 발견하고 수정하라는 업무 과제를 받았습니다. 소스를

programmers.co.kr

문제풀이

👨🏻‍💻 핵심 스킬 👨🏻‍💻
 구현, 시뮬레이션

괄호변환 문제는 괄호를 올바르게 만드는 과정을 구현하는 문제이다. 문제에서는 괄호를 올바르게 변경하는 방법에 대하여 알려주고 있으므로 알려주는 알고리즘을 구현해주기만 하면 된다.

1. 입력이 빈 문자열인 경우, 빈 문자열을 반환합니다. 
2. 문자열 w를 두 "균형잡힌 괄호 문자열" u, v로 분리합니다. 단, u는 "균형잡힌 괄호 문자열"로 더 이상 분리할 수 없어야 하며, v는 빈 문자열이 될 수 있습니다. 
3. 문자열 u가 "올바른 괄호 문자열" 이라면 문자열 v에 대해 1단계부터 다시 수행합니다. 
  3-1. 수행한 결과 문자열을 u에 이어 붙인 후 반환합니다. 
4. 문자열 u가 "올바른 괄호 문자열"이 아니라면 아래 과정을 수행합니다. 
  4-1. 빈 문자열에 첫 번째 문자로 '('를 붙입니다. 
  4-2. 문자열 v에 대해 1단계부터 재귀적으로 수행한 결과 문자열을 이어 붙입니다. 
  4-3. ')'를 다시 붙입니다. 
  4-4. u의 첫 번째와 마지막 문자를 제거하고, 나머지 문자열의 괄호 방향을 뒤집어서 뒤에 붙입니다. 
  4-5. 생성된 문자열을 반환합니다.

문제에서 제시하는 위 1번부터 4번의 과정을 순서대로 구현해주기만 하면 된다. 이 때 문자를 구할 때 재귀를 사용해주면 된다.

 

if(input.length() == 0)
    return "";

1. 빈 문자열인지 확인하고 리턴만 해주면 된다.

 

int checkPoint = 0;

int find = 0;
Stack<Character> stack = new Stack<>();
do{
    stack.add(input.charAt(checkPoint));
    if(input.charAt(checkPoint++) == '(')
        find++;
    else
        find--;
}while (find != 0);

2.  문자열을 u와 v로 쪼개어주는데 u는 최소한의 괄호의 수가 맞는 경우이다. 이 때 괄호가 올바르지는 않아도 되며 열린 괄호와 닫힌 괄호의 개수가 동일해지는 최소 위치를 찍어주면 된다. 나는 find라는 변수를 두고 그 값이 '(' 일 경우 +1을 해주고 ')'의 경우 -1을 해주어 0이 될 때를 찾기로 하였다. 이 때 값을 체크하는 checkPoint 변수를 지정하여 최종적으로 균형잡힌 괄호의 값인 u를 구할수 있게 된다.

 

int closeCount = 0;
boolean isRight = true;
while (!stack.isEmpty()){
    char p = stack.pop();
    if(p == ')')
        closeCount ++;
    else
        closeCount --;
    if(closeCount < 0){
        isRight = false;
        break;
    }
}

3. 위에서 구한 u의 값이 올바른 괄호 문자열인지 확인하는 과정이다. 올바른 괄호의 경우 우측에서부터 좌측으로 확인할 때 닫는 괄호의 개수가 여는 괄호보다 많거나 같아야하므로 돌아가면서 혹시나 여는 괄호가 더 많은지 확인하여 체크해준다.

 

if(isRight) {
    return input.substring(0, checkPoint) + solve(input.substring(checkPoint));
}

3-1. 만약 u가 올바른 괄호라면 v에 대해 위 과정을 반복하여 붙여주었다. 

 

String result = "(" + solve(input.substring(checkPoint)) + ")";

4-1, 4-2, 4-3을 수행한 결과이다. 4-1은 여는괄호를 4-2는 v에 대한 실행을 4-3은 닫는 괄호를 붙여주도록 한다.

String u = input.substring(1,checkPoint-1);
String reverseU = "";
for(int i = 0; i < u.length(); i ++){
    if(u.charAt(i) == '(')
        reverseU = reverseU + ")";
    else
        reverseU = reverseU + "(";
}
return result + reverseU;

4-4, 4-5 u의 양 끝 값을 지워주고, u의 괄호를 각각 뒤집어줍니다. 그리고 뒤집어준 괄호를 위에서 생성한 괄호에 붙여서 return해주어 문제를 해결하였습니다.

구현코드

import java.util.Stack;

public class Solution {
    public String solution(String p) {
        return solve(p);
    }

    public String solve(String input){
        if(input.length() == 0)
            return "";
        int checkPoint = 0;

        int find = 0;
        Stack<Character> stack = new Stack<>();
        do{
            stack.add(input.charAt(checkPoint));
            if(input.charAt(checkPoint++) == '(')
                find++;
            else
                find--;
        }while (find != 0);

        int closeCount = 0;
        boolean isRight = true;
        while (!stack.isEmpty()){
            char p = stack.pop();
            if(p == ')')
                closeCount ++;
            else
                closeCount --;
            if(closeCount < 0){
                isRight = false;
                break;
            }
        }

        if(isRight) {
            return input.substring(0, checkPoint) + solve(input.substring(checkPoint));
        }

        String result = "(" + solve(input.substring(checkPoint)) + ")";
        String u = input.substring(1,checkPoint-1);
        String reverseU = "";
        for(int i = 0; i < u.length(); i ++){
            if(u.charAt(i) == '(')
                reverseU = reverseU + ")";
            else
                reverseU = reverseU + "(";
        }
        return result + reverseU;
    }
}

 

잘못된 지식이나 궁금한 내용이 있을 경우 편하게 댓글 남겨주시면 감사하겠습니다 :)

 

728x90
728x90
저작자표시 비영리 (새창열림)

'CodingTest > Programmers' 카테고리의 다른 글

[PGM_81302] 거리두기 확인하기 (java)  (0) 2022.02.09
[PGM_17677] 뉴스 클러스터링 (java)  (0) 2022.02.08
[PGM_72411] 메뉴 리뉴얼 (java)  (0) 2022.02.04
[PGM_77485] 행렬 테두리 회전하기 (java)  (0) 2022.02.01
[PGM_12973] 짝지어 제거하기 (java)  (0) 2022.01.31
    'CodingTest/Programmers' 카테고리의 다른 글
    • [PGM_81302] 거리두기 확인하기 (java)
    • [PGM_17677] 뉴스 클러스터링 (java)
    • [PGM_72411] 메뉴 리뉴얼 (java)
    • [PGM_77485] 행렬 테두리 회전하기 (java)
    JinSeopKim
    JinSeopKim
    기록📚

    티스토리툴바