问:
- 给定一个元素都为整数的二维数组matrix。假设从矩阵的最左侧选一个数作为开始。每次可以选择当前数的右侧、右上、右下的数累加。当某一次累加和小于0或者走到最后一列游戏结束。在选择的过程中,有一次正负替换的机会(即把当前数变为相反数)。问,累加和最多可以是多少。
- 给定一个字符串str。str表示一个公式。公式里可能有整数、加减乘除符号和左右括号。返回公式的计算结果。例如:str='48*((70-65)-43)+8* 1',返回-1816
解:
- 递归返回两个值,分别是不用正负替换能达到的最大值,用正副替换能达到的最大值。取更大的就可以。
// 暴力递归
function getMaxSum(matrix) {
let res = 0
for (let i = 0; i < matrix.length; i++) {
const { no, yes } = getRes(i, 0)
res = Math.max(no, yes, res)
}
return res
function getRes(row, col) {
if (row < 0) return {
no: 0,
yes: 0
}
if (col === 0) {
return {
no: matrix[row][col],
yes: -matrix[row][col]
}
}
let no = -1
let yes = -1
if (row > 0) {
const leftUp = getRes(row - 1, col - 1)
if (leftUp.no > 0) no = leftUp.no
if (leftUp.yes > 0) yes = leftUp.yes
}
const left = getRes(row, col - 1)
if (left.no > 0) no = Math.max(no, left.no)
if (left.yes > 0) no = Math.max(yes, left.yes)
if (row < matrix.length - 1) {
const leftDown = getRes(row + 1, col - 1)
if (leftDown.no > 0) no = Math.max(no, leftDown.no)
if (leftDown.yes > 0) no = Math.max(yes, leftDown.yes)
}
let curNo = -1
let curYes = -1
if (no > 0) {
curNo = no + matrix[row][col]
curYes = no - matrix[row][col]
}
if (yes > 0) {
curYes = Math.max(curYes, curYes + matrix[row][col])
}
return {
no: curNo,
yes: curYes
}
}
}
- 设定一个临时变量curNum存储数字,遍历str,碰到数字就跟curNum相加,碰到运算符号就判断栈顶是不是乘除。是的话就取出来两个元素跟curNum计算一次,然后把结果加到栈里。如果不是就直接加到栈里。碰到左括号,直接从左括号下一位开始递归这个过程。碰到右括号时结算栈内数据,返回计算结果和位置信息给左括号即可。遍历完毕后结算栈内数据。
function getComputedResult(str) {
function getRes(i) {
const stack = []
let curNum = ''
let res = 0
while (i <= str.length) {
if (['+', '-', '*', '/'].includes(str[i])) {
curNum = isCount(stack, curNum)
stack.push(curNum, str[i++])
curNum = ''
} else if (['('].includes(str[i])) {
const { res,idx } = getRes(i + 1)
curNum = res
i = idx
} else if (str[i] === ')' || i === str.length){
curNum = isCount(stack, curNum)
stack.push(curNum)
i++
// 最后结算栈内全部数据
res = settlement(stack)
return {
res,
idx: i
}
} else {
// 如果是数字
curNum += str[i++]
}
}
}
const { res } = getRes(0)
return res
// 结算栈内数据
function settlement(stack) {
let res = 0
let fh = ''
while (stack.length) {
const cur = stack.shift()
if (cur !== '+' && cur !== '-') {
if (fh === '+' || fh === '') res += +cur
if (fh === '-') res -= +cur
} else {
fh = cur
}
}
return res
}
function isCount (selfStack, curNum) {
// 栈顶是否是乘除,是的话计算一次
const last = selfStack[selfStack.length - 1]
if (last === '*' || last === '/') {
const fh = selfStack.pop()
const num = selfStack.pop()
curNum = fh === '*' ? +num * curNum : (+num / curNum).toFixed(2)
}
return curNum
}
}