持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第18天,点击查看活动详情
动态规划(Dynamic Programming)是一种分阶段求解决策问题的数学思想,它通过把原问题分解为简单的子问题来解决复杂问题。
为运算表达式设计优先级
给你一个由数字和运算符组成的字符串 expression ,按不同优先级组合数字和运算符,计算并返回所有可能组合的结果。你可以 按任意顺序 返回答案。
生成的测试用例满足其对应输出值符合 32 位整数范围,不同结果的数量不超过 104 。
示例 1:
输入:expression = "2-1-1"
输出:[0,2]
解释: ((2-1)-1) = 0
(2-(1-1)) = 2
示例 2:
输入:expression = "23-45"
输出:[-34,-14,-10,-10,10]
解释:
(2*(3-(4*5))) = -34
((23)-(45)) = -14
((2*(3-4))*5) = -10
(2*((3-4)*5)) = -10
(((2*3)-4)*5) = 10
首先我们要对原算式进行预处理,把每个数字提前转为 int
然后存起来,同时把运算符也都存起来。
然后定义dp[i][j]
是第 i
到第 j
个数字范围内的表达式的所有解。初始条件比较简单,就是范围内只有一个数字。然后依次求出包含所有数字的解,即dp[0][n-1]
就是最后的答案。
fun diffWaysToCompute(input: String): List<Int> {
val numList: MutableList<Int> = ArrayList()
val opList: MutableList<Char> = ArrayList()
val array = input.toCharArray()
var num = 0
for (i in array.indices) {
if (isOperation(array[i])) {
numList.add(num)
num = 0
opList.add(array[i])
continue
}
num = num * 10 + array[i].toInt() - '0'.toInt()
}
numList.add(num)
val count = numList.size
val dp = Array(count) { arrayOfNulls<ArrayList<*>>(count)} as Array<Array<ArrayList<Int>>>
for (i in 0 until count) {
val result = ArrayList<Int>()
result.add(numList[i])
dp[i][i] = result
}
for (n in 2..count) {
for (i in 0 until count) {
val j = i + n - 1
if (j >= count) {
break
}
val result = ArrayList<Int>()
for (s in i until j) {
val result1 = dp[i][s]
val result2 = dp[s + 1][j]
for (integer in result1) {
for (value in result2) {
val op = opList[s]
result.add(caculate(integer, op, value))
}
}
}
dp[i][j] = result
}
}
return dp[0][count - 1]
}
复杂度分析
-
时间复杂度:O(2^n)
-
空间复杂度:O(2^n)