/** * https://leetcode.cn/problems/evaluate-reverse-polish-notation/?envType=study-plan-v2&envId=top-interview-150 * @param {string[]} tokens * @return {number} */ const evalRPN = function (tokens) { }; /* 根据逆波兰表达式的规则,我们只需要使用一个栈来存操作数即可,遍历tokens,如果遇到的是 '+' '-' '*' '/' 这些操作符,直接弹出两个元素right和left,之和拿left opt right,之后把计算的结果放入栈中,继续此操作 在最后栈中只会右一个元素,这个元素就是整个波兰表达式的结果 */ function f1(tokens) { const stack = []; let left; let right; for (let i = 0; i < tokens.length; i++) { if (tokens[i] === '+') { right = stack.pop(); left = stack.pop(); stack.push(left + right); } else if (tokens[i] === '-') { right = stack.pop(); left = stack.pop(); stack.push(left - right); } else if (tokens[i] === '*') { right = stack.pop(); left = stack.pop(); stack.push(left * right); } else if (tokens[i] === '/') { right = stack.pop(); left = stack.pop(); let result = left / right; if (result >= 0) { result = Math.floor(result); } else { result = Math.ceil(result); } stack.push(result); } else { stack.push(+tokens[i]); // 转换成number } } return stack.pop(); } /* 优化上面的分支,right = stack.pop();left = stack.pop(); 明显冗余,所以,先判断这个token是否是操作符 如果不是操作符那么它一定是数字字符,就把它转换成数组压入栈中,如果是操作符,就先弹出两个操作数,计数之后把它 压入栈中,在js中触发要特殊处理,因为js不像其他语言会把小数部分去掉 */ function f2(tokens) { const stack = []; const n = tokens.length; for (let i = 0; i < n; i++) { const token = tokens[i]; if (token === '+' || token === '-' || token === '*' || token === '/') { // 先弹出两个操作数 const right = stack.pop(); const left = stack.pop(); // 根据具体操作符进行具体操作 if (token === '+') { stack.push(left + right); } else if (token === '-') { stack.push(left - right); } else if (token === '*') { stack.push(left * right); } else { // 除法操作要特殊处理 stack.push(left / right > 0 ? Math.floor(left / right) : Math.ceil(left / right)); } } else { stack.push(parseInt(token, 10)); } } return stack.pop(); } /* 思路和上面一致,但是不使用栈,而是使用一个数组来储存要操作的数,用一个下标指向数组的最后一个元素, 可以理解成栈顶的元素,波兰表达式的长度n一定为奇数,所以除去操作数,应该有n+1/2个数,所以数组的长度 设置为n+1/2 */ function f3(tokens) { const n = tokens.length; const optNums = new Array(Math.floor((n + 1) / 2)).fill(0); let index = -1; // 指向optNums中最后一个元素 for (let i = 0; i < n; i++) { const token = tokens[i]; if (token === '+') { index--; optNums[index] += optNums[index + 1]; } else if (token === '-') { index--; optNums[index] -= optNums[index + 1]; } else if (token === '*') { index--; optNums[index] *= optNums[index + 1]; } else if (token === '/') { index--; const result = optNums[index] / optNums[index + 1]; optNums[index] = result > 0 ? Math.floor(result) : Math.ceil(result); } else { // token 为数字,将它存入optNums中 index++; optNums[index] = parseInt(token, 10); } } return optNums[index]; }