algorighm/top-interview-leetcode150/stack/150逆波兰表达式.js

115 lines
3.7 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 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];
}