(MEDIUM) https://leetcode.com/problems/different-ways-to-add-parentheses/
Example 1:
Input: expression = "2-1-1"
Output: [0,2]
Explanation:
((2-1)-1) = 0
(2-(1-1)) = 2
Example 2:
Input: expression = "2*3-4*5"
Output: [-34,-14,-10,-10,10]
Explanation:
(2*(3-(4*5))) = -34
((2*3)-(4*5)) = -14
((2*(3-4))*5) = -10
(2*((3-4)*5)) = -10
(((2*3)-4)*5) = 10
0부터 8까지 나열할 수 있는 모든 가짓수 에 대해 계산하는 것이다.class Solution:
def diffWaysToCompute(self, expression: str) -> List[int]:
# 주어진 expression 문자열을 number와 operator로 parse하는 과정
expressionList = []
num_st, num_end = 0, 0
while num_end < len(expression):
if ord('0') <= ord(expression[num_end]) <= ord('9'):
num_end += 1
continue
expressionList.append(int(expression[num_st:num_end]))
expressionList.append(expression[num_end])
num_st = num_end = num_end + 1
if num_st > 0:
expressionList.append(int(expression[num_st:]))
# 주어진 숫자와 operator를 바탕으로 계산
def calcOperation(firstNum, operation, secondNum):
if operation == '+':
return firstNum + secondNum
elif operation == '-':
return firstNum - secondNum
else:
return firstNum * secondNum
ans = set()
def selectOperation(expressionList):
# 주어진 expressionList가 3일 경우 계산된 값을 ans에 추가
if len(expressionList) == 3:
ans.add(calcOperation(expressionList[0], expressionList[1], expressionList[2]))
return
# expressionList 내의 모든 operator에 대해 반복 작업
for idx in range((len(expressionList) - 1) // 2):
# tmp: 선택된 operator의 계산 결과를 포함한 새로운 expressionList
tmp = []
if idx > 0:
tmp.extend(expressionList[:(idx*2)])
tmp.append(calcOperation(expressionList[idx*2], expressionList[idx*2+1], expressionList[idx*2+2]))
if idx < (len(expressionList) - 3) // 2:
tmp.extend(expressionList[(idx*2 + 3):])
selectOperation(tmp)
if len(expressionList) == 1:
return expressionList
selectOperation(expressionList)
return list(ans)
첫 번째 operator 선택 -> 네 번째 operator 선택 과 '네 번째 operator 선택 -> 첫 번째 operator 선택` 을 다른 값으로 인식하게 된다. 다시 말해, operator가 8개 있다면 8! 개의 값을 출력하게 된다는 것이다.선택된 operator의 왼쪽과 오른쪽 expressionList에서 가능한 value들을 list로 각각 받아와, 해당 값들을 계산해 반환 해주는 방식으로 최종적인 알고리즘을 구현했다. from itertools import product
class Solution:
def diffWaysToCompute(self, expression: str) -> List[int]:
# 주어진 expression 문자열을 number와 operator로 parse하는 과정
expressionList = []
num_st, num_end = 0, 0
while num_end < len(expression):
if ord('0') <= ord(expression[num_end]) <= ord('9'):
num_end += 1
continue
expressionList.append(int(expression[num_st:num_end]))
expressionList.append(expression[num_end])
num_st = num_end = num_end + 1
expressionList.append(int(expression[num_st:]))
# 주어진 숫자와 operator를 바탕으로 계산
def calcOperation(firstNum, operation, secondNum):
if operation == '+':
return firstNum + secondNum
elif operation == '-':
return firstNum - secondNum
else:
return firstNum * secondNum
# expressionList 내의 모든 opereator에 대해,
# operator 왼쪽의 expressionList와 오른쪽의 expressionList에 대해 계산 가능한 값들을 가져와
# list에서 하나씩 가져와 모두 계산해준 list를 반환
def selectOperation(expressionList):
if len(expressionList) == 1:
return expressionList
ans = []
for idx in range((len(expressionList) - 1) // 2):
operator = expressionList[idx * 2 + 1]
for firstNum, secondNum in product(selectOperation(expressionList[:(idx*2+1)]), selectOperation(expressionList[(idx*2+2):])):
ans.append(calcOperation(firstNum, operator, secondNum))
return ans
return selectOperation(expressionList)

class Solution(object):
def diffWaysToCompute(self, input):
m = {}
return self.dfs(input, m)
def dfs(self, input, m):
if input in m:
return m[input]
if input.isdigit():
m[input] = int(input)
return [int(input)]
ret = []
for i, c in enumerate(input):
if c in "+-*":
l = self.diffWaysToCompute(input[:i])
r = self.diffWaysToCompute(input[i+1:])
ret.extend(eval(str(x)+c+str(y)) for x in l for y in r)
m[input] = ret
return ret
isdigit() 함수를 잘 이용해 보다 가볍게 iteration을 돌 수 있다는 사실을 알게 되었다.