오늘 문제는 백준이 아닌 프로그래머스 문제입니다. 계속 진행해왔던 스택 자료구조 유형의 문제입니다. 한 번 살펴볼까요?
배열 arr가 주어집니다. 배열 arr의 각 원소는 숫자 0부터 9까지로 이루어져 있습니다. 이때, 배열 arr에서 연속적으로 나타나는 숫자는 하나만 남기고 전부 제거하려고 합니다. 단, 제거된 후 남은 수들을 반환할 때는 배열 arr의 원소들의 순서를 유지해야 합니다. 예를 들면,
배열 arr에서 연속적으로 나타나는 숫자는 제거하고 남은 수들을 return 하는 solution 함수를 완성해 주세요.
arr | answer |
---|---|
[1,1,3,3,0,1,1] | [1,3,0,1] |
[4,4,4,3,3] | [4,3] |
입출력 예 #1,2
문제의 예시와 같습니다.
이 문제는 배열에서 연속적으로 중복된 숫자를 제거하고, 남은 숫자들을 배열의 순서를 유지하면서 반환하는 문제입니다. 즉, 연속된 중복된 숫자를 하나로 축약하여 배열을 만들어야 합니다. 문제를 해결하기 위한 핵심 아이디어는 바로 연속된 숫자의 중복을 확인하고 제거하는 것입니다.
이 문제는 두 가지 방법으로 해결할 수 있습니다:
스택 자료구조를 사용하면, 데이터를 순차적으로 처리하면서 조건에 따라 저장할지 여부를 결정할 수 있습니다. 스택을 사용하지 않더라도 단순히 반복문을 통해 이전 원소와 비교하여 연속된 숫자를 제거하는 방식으로도 풀 수 있습니다.
from collections import deque
def solution(arr):
stack = deque() # 스택으로 사용할 deque 생성
for num in arr: # 배열의 각 숫자에 대해
if not stack or stack[-1] != num: # 스택이 비었거나, 마지막 숫자가 현재 숫자와 다르면
stack.append(num) # 스택에 숫자 추가
return list(stack) # 스택을 리스트로 변환하여 반환
deque
를 스택처럼 사용하여, 숫자를 차례대로 처리하면서 스택의 마지막에 있는 숫자와 현재 숫자를 비교합니다. 만약 연속되지 않으면 스택에 숫자를 추가합니다.핵심 로직은 if not stack or stack[-1] != num
구문입니다.
n
이라고 하면, 배열을 한 번 순회하므로 의 시간 복잡도를 가집니다.def solution(arr):
result = [arr[0]] # 첫 번째 원소를 결과 리스트에 넣음
for i in range(1, len(arr)): # 두 번째 원소부터 시작하여
if arr[i] != arr[i-1]: # 현재 원소와 이전 원소가 다르면
result.append(arr[i]) # 결과 리스트에 현재 원소 추가
return result
result
리스트에 넣고, 두 번째 원소부터 반복문을 돌며 바로 이전 원소와 비교하는 방식입니다.result
리스트에 그 값을 추가합니다.이 방식도 간단하면서 효율적입니다. 배열의 원소들을 순차적으로 처리하고 바로 이전 원소와 비교하는 방식으로 중복을 제거합니다.
n
이라고 하면, 마찬가지로 배열을 한 번 순회하므로 의 시간 복잡도를 가집니다.append()
와 pop()
연산이 간단하고 명확하게 동작합니다.두 풀이 모두 시간 복잡도는 으로 동일하며, 배열의 길이가 최대 1,000,000 이하로 주어지기 때문에 두 방법 모두 성능 상의 문제는 없습니다.
이번 문제는 연속된 숫자의 중복을 제거하는 간단한 알고리즘 문제였지만, 두 가지 접근 방식으로 해결할 수 있었습니다. 스택을 활용하는 방법과 단순한 반복문 비교 방식을 통해, 문제의 핵심인 중복 제거를 효율적으로 구현할 수 있었습니다.
두 풀이 모두 시간 복잡도 을 가지며, 배열의 크기가 최대 1,000,000까지 주어져도 성능 상의 문제가 없음을 확인할 수 있었습니다.
이 문제는 스택과 배열 탐색의 기본적인 개념을 익히고, 효율적으로 문제를 해결하는 능력을 키울 수 있는 좋은 연습 문제입니다. 또한, 단순한 문제라도 여러 가지 방식으로 접근할 수 있다는 점에서 다양한 풀이 방법을 고민해보는 것도 좋은 학습 방법이 될 것입니다.
어제보다 발전한 개발자가 될거야!!💪