🧩 Algorithm/프로그래머스

[programmers] x만큼 간격이 있는 n개의 숫자, 괄호 회전하기

nerowiki 2024. 4. 9. 22:43
728x90
💡 오늘의 학습 키워드
- x만큼 간격이 있는 n개의 숫자
- 괄호 회전하기

 

🥉 x만큼 간격이 있는 n개의 숫자

문제 링크 : https://school.programmers.co.kr/learn/courses/30/lessons/12954

 

문제 설명

더보기
함수 solution은 정수 x와 자연수 n을 입력 받아,
x부터 시작해x씩 증가하는 숫자를 n개 지니는 리스트를 리턴해야 합니다.
다음 제한 조건을 보고, 조건을 만족하는 함수, solution을 완성해주세요.
제한 조건
x는 -10000000 이상, 10000000 이하인 정수입니다.
n은 1000 이하인 자연수입니다.

 

문제 회고

💡 어떤 문제가 있었고, 나는 어떤 시도를 했는지 그리고 새롭게 안 사실은 무엇인지

반복문으로 간단히 풀 수 있었습니다.
1부터 n까지 반복문을 순회하여 x와 곱해주고 리스트에 저장해주었습니다.

💡 내가 해결한 방식은?
def solution(x, n):
    return [num*x for num in range(1,n+1)]

 


🥈 괄호 회전하기

문제 링크 : https://school.programmers.co.kr/learn/courses/30/lessons/76502

 

문제 설명

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

 

문제 회고

💡 어떤 문제가 있었고, 나는 어떤 시도를 했는지 그리고 새롭게 안 사실은 무엇인지

괄호 문제니 곧바로 stack을 어떻게 사용할 지 생각했습니다. 빠르게 문제 해결 방법은 다음과 같습니다.

  1. 입력 받은 문자열 길이만큼 반복문을 순회합니다. 
  2. 올바른 괄호 문자열인지 판별합니다.
  3. 문자열을 회전합니다.

문자열 리스트 길이만큼 반복문을 순회합니다.

 

올바른 문자열을 판별하는 함수는 문자열 리스트를 받아 따로 구현했습니다.

python에서 stack은 따로 함수가 존재하지 않고 list를 stack처럼 append, pop 으로 사용합니다.

여기서 문자열 회전 로직을 어떻게 할 지 생각하지 못해 stack을 바깥에 구현하는게 좋은가 생각해보았지만
리스트로 간단하게 해결이 가능하다는 것을 생각하고 stack은 내부에 초기화 한 후 사용했습니다.

  1. 입력받은 문자열 리스트를 순차적으로 순회할 때 stack에 열린 괄호를 먼저 판별하고 넣어줍니다.
  2. 스택이 비어있거나 알맞는 닫힌 괄호를 찾지 못했다면 False를 리턴해줍니다.
  3. 만약 닫힌 괄호라면 소괄호, 중괄호, 대괄호인지에 따라 분기를 나누어 stack 마지막 값과 비교하여 pop 해줍니다.
  4. stack이 모두 비었을 때 올바른 괄호 문자열이 되므로 not stack일때 리턴해줍니다.

문자열 회전은 리스트를 인덱스에 맞게 잘라 붙이는 방식으로 간단하게 구현했습니다.

💡 내가 해결한 방식은?
def solution(s):
    answer = 0
    def is_right(s):
        # 스택을 이용한 괄호 문자열 판별
        stack = []
        for bracket in s:
            if bracket in ['(', '{', '[']:
                stack.append(bracket)
            else:
                # 스택이 비어있는 경우 False 반환
                if not stack:
                    return False
                # 닫는 괄호와 스택의 마지막 비교 후 제거
                if bracket == ')' and stack[-1] == '(':
                    stack.pop()
                elif bracket == '}' and stack[-1] == '{':
                    stack.pop()
                elif bracket == ']' and stack[-1] == '[':
                    stack.pop()
                else:
                    return False
                
        return not stack
     
    # 문자열 길이 만큼 반복하기
    for i in range(len(s)):
        # 올바른 괄호 문자열 판별하기
        if is_right(s):
            answer += 1
        # 문자열 회전하기
        s = s[1:] + s[0]

    return answer

 

✍️ TIL

두 번째 문제에서 문자열 회전을 위해 반복문을 또 넣어야 하는건지 deque? queue? 고민을 많이 했는데,
stack을 리스트로 구현하면서 이것도 리스트 내에서 해결 가능하겠다는 생각을 했다.
아직까지 리스트로 모두 해결이 가능한 거같은데 언제까지 이게 통할지 모르겠다. (진짜 리스트로 다 되는건가?) 
TIL을 작성하면서 코드를 보니 for i in range(len(s)) 코드에서 i 를 _ 로 작성해도 좋아보인다.
그리고 is_right 함수를 solution 함수 내부에 구현했는데 main 함수와 구분하는 것처럼 다음에는
그냥 solution 함수 외부에 구현하는게 좀 더 가독성이 좋을 것 같다.
stack을 활용한 구현 문제도 풀어보았으니 다음은 누적합 문제를 찾아봐야겠다.