Notion에서 작성한 글이라, 여기 에서 더 깔끔하게 보실 수 있습니다! 😮🥹
def solution(s):
stack = []
for c in s:
if c == '(':
stack.append(c)
else:
if stack:
stack.pop()
else:
return False
return not stack
stack
에 원소가 없을 때 pop()
하게 되면 IndexError가 발생하기 때문에, 이처럼 if stack
으로 체크한 다음 pop()
하는 방법이 있고, try-except
를 이용하는 방법도 있다.stack
에 굳이 (
를 push할 필요가 없긴 하다.append()
할 때 1을 더하고, pop()
할 때 1을 빼주고, 마지막에 그 값이 0인지 아닌지만 체크해주면 된다.)()(
와 같은 입력이 주어졌을 때 [2]
를 지나고 -1이 되었다가, [3]
에서 다시 0이 되어 마치 올바른 괄호 쌍처럼 보이기 때문에, 해당 변수가 음수가 될 때 False
를 return하는 식으로 작성하여야 한다.from collections import deque
def solution(progresses, speeds):
answer = []
progresses = deque(progresses)
speeds = deque(speeds)
while progresses:
pop_cnt = 0
while progresses[0] < 100:
# progresses = deque(x+y for x,y in zip(progresses, speeds))
for i in range(len(progresses)):
progresses[i] += speeds[i]
while progresses and progresses[0] >= 100:
progresses.popleft()
speeds.popleft()
pop_cnt += 1
answer.append(pop_cnt)
return answer
popleft()
하면서 배포한 개수를 세어준다.zip()
을 이용하는 것이 더 깔끔해보이나 deque로 다시 바꿔주는 과정에서 추가적인 시간이 소모되기 때문에 인덱스로 접근했다.from collections import deque
def solution(progresses, speeds):
answer = []
progresses = deque(progresses)
speeds = deque(speeds)
t = 1
pop_cnt = 0
while progresses:
if progresses[0] + speeds[0]*t >= 100:
progresses.popleft()
speeds.popleft()
pop_cnt += 1
else:
if pop_cnt:
answer.append(pop_cnt)
pop_cnt = 0
t += 1
answer.append(pop_cnt)
return answer
time
을 이용하여, 이를 증가시켜가며 첫 번째 작업의 진행상황만을 체크한다.t
를 증가시키느라 while
loop는 99회 반복된다. 여기에, 작업의 수까지 더해져 회 반복된다.def solution(progresses, speeds):
answer = []
t = 1
pop_cnt = 0
i = 0
while i < len(progresses):
if progresses[i] + speeds[i]*t >= 100:
i += 1
pop_cnt += 1
else:
if pop_cnt:
answer.append(pop_cnt)
pop_cnt = 0
t += 1
answer.append(pop_cnt)
return answer
progress
와 speeds
에서 popleft()
한 정보는 의미를 갖지 않는다. 게다가 리스트로 입력받은 이 둘을 deque
로 바꿔주는 과정에서 각각 의 시간이 소요되기 때문에, deque
를 이용하지 않고 단순히 인덱스로 접근함으로써 계수를 커팅할 수 있다.from math import ceil
def solution(progresses, speeds):
answer = []
t = [ceil((100-p)/s) for p, s in zip(progresses, speeds)]
mx = t[0]
cnt = 1
for i in range(1, len(t)):
if t[i] <= mx:
cnt += 1
else:
answer.append(cnt)
mx = t[i]
cnt = 1
answer.append(cnt)
return answer
ceil()
을 해주는 이유는, 배포가 하루의 끝에 이루어지기 때문이다.from math import ceil
def solution(progresses, speeds):
answer = []
cnt = 0
mx = ceil((100-progresses[0])/speeds[0])
for p, s in zip(progresses, speeds):
cur = ceil((100-p)/s)
if cur <= mx:
cnt += 1
else:
answer.append(cnt)
mx = cur
cnt = 1
answer.append(cnt)
return answer
queue1
, queue2
를 각각 , 라 하자. 두 큐의 합을 같게 만든다는 것은,-1
을 return해주면 된다.popleft()
한 다음, 작은 queue에 append()
해주는 과정을 반복한다.popleft()
, append()
하고 나면 서로 swap된 형태가 되므로 이 때부턴 더이상 작업하는 것이 의미가 없을 것이라고 판단했다. → WACounterExample
Input:
[1, 1, 1, 1], [1, 1, 7, 1]Expected:
9
sum()
과 같이 에 확인하면 무조건 TLE가 난다. 한 번의 작업에서 어떤 queue에서 pop되면 다른 queue에 append된다는 점에 주목하여, Prefix Sum이나 Sliding Window와 비슷한 느낌으로 매 작업마다 에 처리해주면 된다.from collections import deque
def solution(queue1, queue2):
queue1 = deque(queue1)
queue2 = deque(queue2)
psum1 = sum(queue1)
psum2 = sum(queue2)
if (psum1+psum2)%2: return -1
limit = len(queue1)*3-3
cnt = 0
while cnt <= limit:
if psum1 < psum2:
cur = queue2.popleft()
queue1.append(cur)
psum1 += cur
psum2 -= cur
elif psum2 < psum1:
cur = queue1.popleft()
queue2.append(cur)
psum2 += cur
psum1 -= cur
else: return cnt
cnt += 1
return -1
def solution(queue1, queue2):
merged_queue = queue1 + queue2
psum1 = sum(queue1)
psum2 = sum(queue2)
if (psum1+psum2)%2: return -1
cnt = 0
l, r = 0, len(queue1)
while l<r and r<len(merged_queue):
if psum1 < psum2:
psum1 += merged_queue[r]
psum2 -= merged_queue[r]
r += 1
elif psum2 < psum1:
psum1 -= merged_queue[l]
psum2 += merged_queue[l]
l += 1
else: return cnt
cnt += 1
return -1
l
, r
을 조정해가며 기존 방식과 매우 유사하게 풀 수 있다. 이를 통해 더 직관적으로 최대 번까지만 체크해주면 된다는 것을 확인할 수 있다.r
이 밖으로 나가는 경우는 곧 불가능한 케이스를 의미한다. r
이 인덱스 범위 밖으로 나가는 경우에 유의해야 한다.Middler
math.ceil()
없이 올림 구현해봐야 겠다.Challenger Solution 2.
psum1
, psum2
중 하나는 갱신해주지 않아도 될 것 같다. 이 방법으로 상수커팅을 좀 해볼 수 있겠고,merged_queue
를 위와 같이 만들면 의 시간이 소요되는데, 어차피 이후에 각각의 큐를 분리해서 생각할 필요가 없어지므로 extend()
로 에 처리하면서 계수커팅을 해볼 수 있겠다.l
이 구간에 존재할 땐 queue2
를 참조하는 식으로 합치는 데 드는 시간을 아예 소모하지 않도록 바꿀 수 있어보인다. 요새 시간이 너무너무 없어서... 나중에 더 타이트하게 쥐어짜봐야 겠다.