defsolution(int_arr): for i inrange(len(int_arr)): int = int_arr[i] result = -1 for j inrange(i,len(int_arr)): ifint < int_arr[j]: result = int_arr[j] break print(f"{int} --> {result}")
스택
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
defsolution*by_stack(int_arr): n = len(int_arr) s = [] res = [-1for * inrange(len(int_arr))]
for i inrange(n-1,-1,-1): while s: if s[-1] > int_arr[i]: res[i] = s[-1] break else: s.pop() s.append(int_arr[i])
for i inrange(n): print(f"{int_arr[i]} --> {res[i]}")
현재 원소와 오른쪽 원소를 비교하므로, 오른쪽에서 왼쪽으로 이동하면서 비교하면 수월하다.
문제에서 요구하는 것은 현재 원소의 오른쪽 값 중 가장 가까운 값이므로, 오른쪽 부터 왼쪽으로 가면서 원소를 저장했다면 꺼낼 때는 역순으로 꺼내서 비교한다.
stack을 빈 상태로 초기화
res 배열을 -1로 배열 길이 만큼 초기화
역순으로 순회를 하면서 stack이 비어있으면, 원소를 추가한다.
만약 stack에 값이 있다면, 스택의 값들과 현재 원소를 비교한다.
스택의 값이 크다면 해당 원소의 index에 위치하는 res 배열에 스택의 값을 할당하고 해당 원소를 stack 저장
defsolution(str): priority = {'+':2,'-':2,'*':1,'/':1} result = '' s = []
for x instr: if x.isnumeric(): result += x elif x == '(': s.append(x) elif x == ')': while s[-1] != "(": result += s.pop() s.pop() elif x in priority: if s and s[-1] != '('and priority[s[-1]] < priority[x]: result += s.pop() s.append(x)
while s: result += s.pop()
return result
코딩테스트를 본다고 생각하고 리스트를 활용하여 위 문제를 풀어보았다.
isnumeric() 함수는 문자열이 숫자인지 판단하는 메서드이다.
stack의 top을 의미하는 s[-1] 슬라이싱을 활용하였다.
빈 리스트는 논리값이 False라는 점을 활용하여 while 반복문을 실행했다.
후위 표기법 계산하기
문자열을 순회하면서 해당 문자가 숫자면 정수형으로 변환하여 스택에 push
연산자이면 스택에서 두 수를 pop하여 계산
스택은 후입선출이므로, 처음 pop한 수를 n2, 두번째 pop한 수를 n1으로 두고 (n1 연산자 n2)로 계산한다.
계산결과를 스택에 push
스택에 마지막에 저장된 값이 결과값이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
defeval_postfix(expression): s = [] for exp in expression: if exp.isnumeric(): s.append(int(exp)) elif exp != " ": n2 = s.pop() n1 = s.pop() if exp == '+': res = n1 + n2 elif exp == '-': res = n1 - n2 elif exp == '*': res = n1 * n2 else: res = n1 / n2 s.append(res) return s[0]
defsolution(str): priority = {'+':2,'-':2,'*':1,'/':1} s = Stack()
result = '' for x instr: if x notin priority.keys(): result += x else: if s.top == None: s.push(x) else: if priority[s.top.data] < priority[x]: s_pop = s.pop() result += s_pop s.push(x)
whilenot s.is_empty(): s_pop = s.pop() result += s_pop
return result
아래는 if 문으 조금 줄여보았다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
defsolution(str): priority = {'+':2,'-':2,'*':1,'/':1} s = Stack()
result = '' for x instr: if x notin priority.keys(): result += x else: ifnot s.is_empty() and priority[s.top.data] < priority[x]: s_pop = s.pop() result += s_pop s.push(x)
whilenot s.is_empty(): s_pop = s.pop() result += s_pop
for x instr: if x in brackets.values(): stack.push(x) elif x in brackets: popped = stack.pop() ifnot popped or brackets[x] != popped: returnFalse return stack.is_empty()
brackets을 관리하는 딕셔너리를 만든다.
여는 괄호면 stack에 push한다.
닫는 괄호면, 해당 닫는 괄호와 짝을 이루는 여는 괄호가 stack.pop()한 요소와 같은지 비교
만약 다르거나 pop한 요소가 None이라면 False
문제 3. 짝지어 제거하기
같은 알파벳 2개가 붙어 있는 짝을 찾습니다.
그 다음 그 둘을 제거한 뒤 앞뒤로 문자열을 이어 붙입니다.
이 과정을 반복하여 문자열이 모두 제거된다면 1을 반환하고 그렇지 않으면 0을 반환합니다.
풀이
1 2 3 4 5 6 7 8 9
defsolution(str): stack = []
for ch instr: if stack and ch == stack[-1]: stack.pop() else: stack.append(ch) return0if stack else1