package LeetCode_241
import java.util.*
import kotlin.collections.ArrayList
/**
* 241. Different Ways to Add Parentheses
* https://leetcode.com/problems/different-ways-to-add-parentheses/description/
* Given a string of numbers and operators, return all possible results from computing all the different possible ways to group numbers and operators.
* The valid operators are +, - and *.
*
Example 1:
Input: "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
Constraints:
1. 1 <= expression.length <= 20
2. expression consists of digits and the operator '+', '-', and '*'.
* */
class Solution {
/*
* solution:DFS, Memorization with map, split each char to check it digit or symbol and calculate value with operations from left to right
* Time:O(n*2^n), Space:O(2^n)
* */
fun diffWaysToCompute(expression: String): List<Int> {
val map = HashMap<String, List<Int>>()
return dfs(expression, map)
}
private fun dfs(expression: String, map: HashMap<String, List<Int>>): List<Int> {
if (map.containsKey(expression)){
return map.getOrDefault(expression, ArrayList<Int>())
}
val values = ArrayList<Int>()
if (!hasOperations(expression)) {
//just put digit in values
values.add(expression.toInt())
} else {
for (i in expression.indices) {
val c = expression[i]
if (!c.isDigit()) {
val left = dfs(expression.substring(0, i), map)
//substring form current i to the end
val right = dfs(expression.substring(i + 1), map)
//check each digit from left sub list and right sub list
for (l in left) {
for (r in right) {
when (c) {
'+' -> values.add(l + r)
'-' -> values.add(l - r)
'*' -> values.add(l * r)
}
}
}
}
}
}
//save into map for next level
map.put(expression, values)
return values
}
private fun hasOperations(expression: String):Boolean{
for (c in expression){
if (c=='+' || c=='-' || c=='*'){
return true
}
}
return false
}
}