[C#]월간코드챌린지 시즌2 -괄호 회전하기

2021. 4. 21. 20:06[C#] 코딩테스트 문제풀이

반응형

문제 설명

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

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

 

첫번째 풀이 (스택 x,월간 코드 챌린지 당시)

using System;
using System.Collections.Generic;
public class Solution {
    public static char[] CircularShiftLeft(char[] arr, int shifts)
    {
        var dest = new char[arr.Length];
        Array.Copy(arr, shifts, dest, 0, arr.Length - shifts);
        Array.Copy(arr, 0, dest, arr.Length - shifts, shifts);
        return dest;
    }
    
    public int solution(string s) {
        int answer = 0;
        Char[] temp = s.ToCharArray();
        int resultcount =0;
        int rightopen =0;
        int leftopen =0;
        for(int i=0; i<temp.Length; i++)
        {
            if(temp[i]=='['||temp[i]=='{'||temp[i]=='(') rightopen++;
            else leftopen++;
        }
        //괄호 개수가 안맞는 경우.
        if(rightopen != leftopen) return 0;
        
        //괄호가 올바르지 못할경우.
        else
        {
            while(resultcount<s.Length)
            {
                List<int> Count = new List<int>(){0,0,0,0,0,0};
                for(int i=0; i<temp.Length; i++)
                {
                    if(temp[i] == '[')
                    {
                        Count[0]++;
                    }
                    else if(temp[i] == ']')
                    {
                        Count[1]++;
                        if(Count[0]<Count[1]) 
                        {
                            resultcount++;
                            temp =CircularShiftLeft(temp,1);
                            break;
                        }
                    }
                    else if(temp[i] == '{')
                    {
                        Count[2]++;
                    }
                    else if(temp[i] == '}')
                    {
                        Count[3]++;
                        if(Count[2]<Count[3]) 
                        {
                            resultcount++;
                            temp =CircularShiftLeft(temp,1);
                            break;
                        }
                    }
                    else if(temp[i] == '(')
                    {
                        Count[4]++;
                    }
                    else if(temp[i] == ')')
                    {
                        Count[5]++;
                        if(Count[4]<Count[5]) 
                        {
                            resultcount++;
                            temp =CircularShiftLeft(temp,1);
                            break;
                        }
                    }
                    if(i == temp.Length-1)
                    {
                        answer++;
                        resultcount++;
                        temp =CircularShiftLeft(temp,1);
                        //break;
                    }
                }
            }
        }
        return answer;
    }
}

필자가 월간 코드 챌린지에 참여할 때만해도 문제의 테스트 케이스에 '{[}]' 같은 경우의 올바르지 못한 괄호 구조가 나오는 테스트 케이스가 없어 위의 코드로 카운트로만 세어줘도 문제 없이 해결 되었으나, 프로그래머스 사이트에 올라온 문제를 다시 풀 때에는 테스트 케이스에 추가 되어 스택영역의 카운트 과정을 추가해줘야 했음. 

 

두번째 풀이(스택 O , 프로그래머스 연습문제)

using System;
using System.Collections.Generic;
using System.Linq;
public class Solution {
    public static char[] CircularShiftLeft(char[] arr, int shifts)
    {
        var dest = new char[arr.Length];
        Array.Copy(arr, shifts, dest, 0, arr.Length - shifts);
        Array.Copy(arr, 0, dest, arr.Length - shifts, shifts);
        return dest;
    }
    
    public int solution(string s) {
        int answer = 0;
        Char[] temp = s.ToCharArray();
        int resultcount =0;
        int rightopen =0;
        int leftopen =0;

        for(int i=0; i<temp.Length; i++)
        {
            if(temp[i]=='['||temp[i]=='{'||temp[i]=='(') rightopen++;
            else leftopen++;
        }
        //괄호 개수가 안맞는 경우.
        if(rightopen != leftopen) return 0;
        
        //괄호가 올바르지 못할경우.
        else
        {
            while(resultcount<s.Length)
            {
                List<int> Count = new List<int>(){0,0,0,0,0,0};
                List<Char> stack = new List<Char>();
                for(int i=0; i<temp.Length; i++)
                {
                    if(temp[i] == '[')
                    {
                        stack.Add(temp[i]);
                        Count[0]++;
                    }
                    else if(temp[i] == ']')
                    {
                        Count[1]++;
                        if(Count[0]<Count[1]) 
                        {
                            resultcount++;
                            temp =CircularShiftLeft(temp,1);
                            break;
                        }
                        if(stack.Count != 0 &&stack[stack.Count-1]=='[')
                        {
                            stack.RemoveAt(stack.Count-1);
                        }
                        else
                        {
                            resultcount++;
                            temp =CircularShiftLeft(temp,1);
                            break;
                        }
                    }
                    else if(temp[i] == '{')
                    {
                        stack.Add(temp[i]);
                        Count[2]++;
                    }
                    else if(temp[i] == '}')
                    {
                        Count[3]++;
                        if(Count[2]<Count[3] )  
                        {
                            resultcount++;
                            temp =CircularShiftLeft(temp,1);
                            break;
                        }
                        if(stack.Count != 0 &&stack[stack.Count-1]=='{')
                        {
                            stack.RemoveAt(stack.Count-1);
                        }
                        else
                        {
                            resultcount++;
                            temp =CircularShiftLeft(temp,1);
                            break;
                        }
                    }
                    else if(temp[i] == '(')
                    {
                        stack.Add(temp[i]);
                        Count[4]++;
                    }
                    else if(temp[i] == ')')
                    {
                        Count[5]++;
                        if(Count[4]<Count[5] ) 
                        {
                            resultcount++;
                            temp =CircularShiftLeft(temp,1);
                            break;
                        }
                        if(stack.Count != 0 &&stack[stack.Count-1]=='(')
                        {
                            stack.RemoveAt(stack.Count-1);
                        }
                        else
                        {
                            resultcount++;
                            temp =CircularShiftLeft(temp,1);
                            break;
                        }
                    }
                    if(i == temp.Length-1)
                    {
                        answer++;
                        resultcount++;
                        temp =CircularShiftLeft(temp,1);
                    }
                }
            }
        }
        return answer;
    }
}

닫힌 괄호가 나온 시점에 카운트가 정상 적일 경우 열린 괄호만 넣어두었던 Char형 스택의 마지막 괄호가 일치하는지 판단하는 코드를 추가해 주었다.

반응형