TY blog

프로그래머스 [짝지어 제거하기] 본문

알고리즘

프로그래머스 [짝지어 제거하기]

주짓수하는 개발자 2023. 9. 18. 13:53

프로그래머스 문제에서 슬슬 알고리즘과 코딩테스트를 준비하려는 단계에서 효율성 테스트에서 계속 통과하지 못하는 

상황이 발생했다. 

 

해당문제 사이트 

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

 

프로그래머스

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

programmers.co.kr

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

제한사항

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

 

처음 구현코드
class Solution
{
    public int solution(String s)
    {
        int answer = 0;
        int num = 0;
        String str = "";
        int index = 0; 
    
        str = s.charAt(0)+"";
        
        for(int i=1; i < s.length(); i++){
            if(str.length() != 2){
                if(str.charAt(0) == s.charAt(i)){
                    str += str;
                    num = s.length();
                    s = s.replace(str, "");
                    index = num - s.length();
                    if(i > index) i = i-index;
                    else i = 0;
                    
                    if(s.length() > i ) str= s.charAt(i)+"";
                    else return 1;
                        
                }else{
                    str = s.charAt(i)+"";
                }
            }
            
        }
        
        return s.length() == 0 ? 1 : 0 ;
    }
}

문자열 S에서 연속으로 이어진 문자열(바꿀 수 있는 문자열)을 이어 붙이고 공백으로 치환 후 다시 이전 인덱스로 돌아가서 탐색 후 최종 반복문을 빠져나갈 때 s.length() 길이를 확인해서 1인지 0인지를 리턴하는 코드를 작성했다. 

 

첫 번째 시도 결과

정확성 테스트
효율성 테스트

내가 구현한 코드에서 문자열을 찾으면 이전 Index로 돌아가는 단계에서 효율성이 떨어졌다.

다른 방식으로는 자료구조 Stack을 사용하여 담긴 문자열을 비교하여 Pop 하는 연산을 생각해 코드를 작성했다. 

자료구조 Stack 사용하여 코드 작성하기
import java.util.Stack;

class Solution
{
    public int solution(String s)
    {
        Stack<Character> stack = new Stack<>();
        
        for(int i=0; i<s.length(); i++){
            
            if(!stack.isEmpty() && stack.peek() == s.charAt(i)) stack.pop();
            else stack.push(s.charAt(i));
        }
        return stack.isEmpty() ? 1 : 0 ;
    }
}

처음 구현보단, Stack 자료구조를 이용해서 Stack에 담긴 문자와 현재 문자를 비교만 해서 Pop 연산만 해주면 간단하게 해결할 수 있었다. 

시간복잡도도 S의 길이만큼 걸려 이전코드보다 훨씬 효율적으로 해결했다. 

 

두 번째 시도 결과 

수정코드 정확성 테스트
수정코드 효율성 테스트

 

Comments