짝지어 제거하기 (Level 2)

블랑·2023년 3월 27일
0

Programmers

목록 보기
2/5

문제

https://school.programmers.co.kr/learn/courses/30/lessons/12973

문제 설명

짝지어 제거하기는, 알파벳 소문자로 이루어진 문자열을 가지고 시작합니다.
먼저 문자열에서 같은 알파벳이 2개 붙어 있는 짝을 찾습니다.
그다음, 그 둘을 제거한 뒤, 앞뒤로 문자열을 이어 붙입니다.
이 과정을 반복해서 문자열을 모두 제거한다면 짝지어 제거하기가 종료됩니다.
문자열 S가 주어졌을 때, 짝지어 제거하기를 성공적으로 수행할 수 있는지 반환하는 함수를 완성해 주세요.
성공적으로 수행할 수 있으면 1을, 아닐 경우 0을 리턴해주면 됩니다.

예를 들어, 문자열 S = baabaa 라면,
b aa baa → bb aa → aa →
의 순서로 문자열을 모두 제거할 수 있으므로 1을 반환합니다.

제한사항

문자열의 길이 : 1,000,000이하의 자연수
문자열은 모두 소문자로 이루어져 있습니다.

풀이

  1. 2개 붙어있는 문자열 찾기
  2. 문자열 제거
  3. 1-2를 더 이상 실행할 수 없을때까지 반복
  4. 성공/실패 파악

의 4가지 단계로 이루어져 있다.

첫 번째로는 재귀함수를 통해 값을 구현하였는데, 이는 코드 실행 자체는 되나 시간 초과 오류가 발생하였다.

이를 개선하고자 스택을 사용해서 peek를 통해 값이 맞는다면 뽑아서 제거하고, 반복하는 방식을 생각해 구현하였다.

자세한 것은 코드 1과 2의 주석을 참고하자.

코드

재귀(시간 초과)

class Solution
{
    public int solution(String s)
    {
        int cnt = 1;
        int sLength = s.length(); //남은 문자열의 길이를 담을 변수
        while (cnt < s.length()) {
            if(s.charAt(cnt - 1) == s.charAt(cnt)) {
                s = deleteString(s, cnt - 1, cnt); //줄어든 문자열을 다시 리턴
                //변수 갱신
                sLength = s.length();
                cnt = 0;
            }
            cnt += 1;
        }
        
        if(s.length() != 0) return 0;
        else return 1;
    }
    
     private static String deleteString(String s, int leftIdx, int rightIdx) {
        while(true) {
            //OutOfIdx이거나, 비교값이 다르다면 탈출
            if(leftIdx < 0 || rightIdx >= s.length() || s.charAt(leftIdx) != s.charAt(rightIdx)) break;
            leftIdx -= 1;
            rightIdx += 1;
        }
        //인덱스 반환
        leftIdx += 1;
        rightIdx -= 1; 

        String res = "";
        if(leftIdx > 0) res += s.substring(0, leftIdx);
        if(rightIdx < s.length()) res += s.substring(rightIdx + 1);
        return res;
    }
}

스택 사용(통과)

import java.util.*;
class Solution
{
    public int solution(String s)
    {
       Stack<Character> stack = new Stack<>();
        for (int i = 0; i < s.length(); i++) {
            boolean flag = false; //TF 판별용 변수
            char now = s.charAt(i); //현재 판단 문자열

            while (true) {
                if(stack.isEmpty() || stack.peek() != now) break; //만약 이전 값과 다르다면 벗어남
                flag = true; //같은 값이 있다 = 값을 빼야 한다 = 지금 값(now)는 넣을 필요가 없다.
                stack.pop();
            }
            if(!flag) stack.push(now);
        }

        if(stack.isEmpty()) return 1;
        return 0;
    }
}
profile
안녕하세요.

0개의 댓글