https://school.programmers.co.kr/learn/courses/30/lessons/68646
문제 설명
일렬로 나열된 n개의 풍선이 있습니다. 모든 풍선에는 서로 다른 숫자가 써져 있습니다. 당신은 다음 과정을 반복하면서 풍선들을 단 1개만 남을 때까지 계속 터트리려고 합니다.
- 임의의 인접한 두 풍선을 고른 뒤, 두 풍선 중 하나를 터트립니다.
- 터진 풍선으로 인해 풍선들 사이에 빈 공간이 생겼다면, 빈 공간이 없도록 풍선들을 중앙으로 밀착시킵니다.
여기서 조건이 있습니다. 인접한 두 풍선 중에서 번호가 더 작은 풍선을 터트리는 행위는 최대 1번만 할 수 있습니다. 즉, 어떤 시점에서 인접한 두 풍선 중 번호가 더 작은 풍선을 터트렸다면, 그 이후에는 인접한 두 풍선을 고른 뒤 번호가 더 큰 풍선만을 터트릴 수 있습니다.
당신은 어떤 풍선이 최후까지 남을 수 있는지 알아보고 싶습니다. 위에 서술된 조건대로 풍선을 터트리다 보면, 어떤 풍선은 최후까지 남을 수도 있지만, 어떤 풍선은 무슨 수를 쓰더라도 마지막까지 남기는 것이 불가능할 수도 있습니다.
일렬로 나열된 풍선들의 번호가 담긴 배열 a가 주어집니다. 위에 서술된 규칙대로 풍선들을 1개만 남을 때까지 터트렸을 때 최후까지 남기는 것이 가능한 풍선들의 개수를 return 하도록 solution 함수를 완성해주세요.
규칙을 찾아보면, 가장 양쪽에 놓인 두 풍선은 항상 마지막까지 남길 수 있다.
중간에 놓인 풍선들 중, 양쪽 풍선들 중 가장 작은 풍선 번호 각각을 구했을 때 중앙 풍선 번호보다 둘 다 작은 경우가 아니라면 그 풍선은 마지막까지 남을 수 있다.
중간에 놓인 풍선들의 양쪽 풍선들 중 가장 작은 풍선 번호를 각각 구할 때, min 함수를 사용한다면 시간초과가 날 수도 있다고 생각해서 왼쪽부터 순차적으로 가장 작은 풍선 번호를 저장하는 dp 배열을 만들었다.
또한, 배열 오른쪽의 가장 작은 풍선 번호는 가장 오른쪽 풍선 번호를 시작으로 차례로 갱신하며 진행했다.
<< 전체 코드 >>
def solution(a):
# 가장 양옆 풍선은 무조건 남을 수 있다.
if len(a) <= 2:
return len(a)
answer = 2
# 왼쪽부터 순차적으로 가장 작은 풍선 번호의 dp 구하기
left_minNum_dp = [a[0]]
for i in range(1, len(a)-2):
left_minNum_dp.append(min(a[i], left_minNum_dp[i-1]))
# 오른쪽 풍선들 중 가장 작은 풍선 번호
right_minNum = a[len(a)-1]
# 양쪽의 가장 작은 두 풍선 번호들 모두 해당 풍선 번호보다 작은 경우가 아니면 가능
for i in range(len(a)-2, 0, -1):
if a[i] <= left_minNum_dp[i-1] or a[i] <= right_minNum:
answer += 1
right_minNum = min(right_minNum, a[i])
return answer
'코딩테스트 > 프로그래머스' 카테고리의 다른 글
[프로그래머스 Level3] 모두 0으로 만들기 - 파이썬(Python) - 월간 코드 챌린지 시즌2 (0) | 2022.12.28 |
---|---|
[프로그래머스 Level3] 아이템 줍기 - 파이썬(Python) - 깊이/너비 우선 탐색(DFS/BFS) (0) | 2022.12.27 |
[프로그래머스 Level2] 숫자 카드 나누기 - 파이썬(Python) (0) | 2022.12.27 |
[프로그래머스 Level3] 섬 연결하기 - 파이썬(Python) (0) | 2022.12.13 |
[프로그래머스 Level2] 후보키 - 파이썬(Python) - 2019 KAKAO BLIND RECRUITMENT (0) | 2022.12.09 |