文章目录
- 栈和对列
- Js 有栈与队列吗
- 20. 有效的括号 - 力扣(LeetCode)
- 思路
- 1047. 删除字符串中的所有相邻重复项 - 力扣(LeetCode)
- 思路
- 代码分析
- array.join() 操作打印
- const s of str 操作遍历
- 150. 逆波兰表达式求值 - 力扣(LeetCode)
- 思路
- 代码分析
- js:isNaN()
- JavaScript 位运算符 |
栈和对列
Js 有栈与队列吗
JavaScript 没有内置的栈和队列数据结构,但可以使用数组来模拟它们。
- 栈(Stack)
栈是一种后进先出(LIFO)的数据结构。可以使用数组来实现栈,使用push()
方法向栈顶添加元素,使用pop()
方法弹出栈顶元素。
push()
方法可以接收任意数量的参数,把它们逐个添加到数组末尾,并返回修改后数组的长度。而pop()
方法则从数组末尾移除最后一项,减少数组的length值,然后返回移除的项。
例如:
// 入栈出栈---先进后出
const stack = [];
stack.push(1);
stack.push(2);
stack.push(3);
console.log(stack.pop()); // 3
console.log(stack.pop()); // 2
console.log(stack.pop()); // 1
- 队列(Queue)
队列是一种先进先出(FIFO)的数据结构。可以使用数组来实现队列,使用push()
方法向队尾添加元素,使用shift()
方法弹出队头元素。
例如:
// 入队出队---先进先出
const queue = [];
queue.push(1);
queue.push(2);
queue.push(3);
console.log(queue.shift()); // 1
console.log(queue.shift()); // 2
console.log(queue.shift()); // 3
需要注意的是,使用数组实现队列时,使用 shift()
方法弹出队头元素的时间复杂度为 O(n),因为需要将数组中所有元素向前移动一位。如果需要高效地实现队列,可以使用双端队列(deque)或循环队列(circular queue)。unshift()
方法是向数组的开头添加一个或多个元素,并且返回新的长度。
20. 有效的括号 - 力扣(LeetCode)
思路
代码分析
/*
* @lc app=leetcode.cn id=20 lang=javascript
*
* [20] 有效的括号
*/
// @lc code=start
/**
* @param {string} s
* @return {boolean}
*/
var isValid = function(s) {
/*
如果是左括号,就把相应的右括号,push压入栈
如果是右括号,就弹出当前栈的末尾元素pop,如果匹配,继续上述操作,不匹配返回false
当遍历完所有的字符,栈里面位空,则返回true
*/
/**
* eg ([(){}])
* 技巧:我们匹配左括号的时候,可以让右括号入栈,这样就只需要比较当前元素和栈顶元素是否相等
*/
// 1 建一个栈 数组
const stack = []
// 2 遍历字符串
for(let i = 0; i < s.length; i++) {
// 判断当前的括号是否是左括号,是左括号,入栈(push()),最后入的就是栈顶元素
switch (s[i]) {
case '(':
stack.push(')')
break;
case '[':
stack.push(']')
break;
case '{':
stack.push('}')
break;
default:
// 右括号,如果跟栈顶元素(pop())不相等,false
if(s[i] !== stack.pop())
return false
}
}
// 当元素遍历完了,栈为空,那么返回true
return stack.length === 0
};
// @lc code=end
1047. 删除字符串中的所有相邻重复项 - 力扣(LeetCode)
思路
代码分析
/*
* @lc app=leetcode.cn id=1047 lang=javascript
*
* [1047] 删除字符串中的所有相邻重复项
*/
// @lc code=start
/**
* @param {string} s
* @return {string}
*/
var removeDuplicates = function(s) {
/**
* 删除相邻相同的字符,重复删除直至无法删除(入栈出栈)
*/
// 1 创建栈
const stack = []
// 2 遍历字符串
for(const x of s) {
// 使用c记录弹出的元素是否与当前遍历元素一样,不一样需要把c压回栈中
let c = null
// 3 栈不为空,且当前的字符 === 弹出的字符 跳出循环继续遍历
if(stack.length && x === (c = stack.pop())) continue
// 4 当前字符和弹出字符不一致时,且c存在(栈空的时候不存在),我们把c继续压入栈中,继续进行匹配
c && stack.push(c)
// 5 如果弹出字符没有与当前字符x相等,则把当前的x压入栈
stack.push(x)
}
// 6 返回当前栈 且去掉分隔符
return stack.join("")
};
// @lc code=end
array.join() 操作打印
const s of str 操作遍历
150. 逆波兰表达式求值 - 力扣(LeetCode)
思路
代码分析
/*
* @lc app=leetcode.cn id=150 lang=javascript
*
* [150] 逆波兰表达式求值
*/
// @lc code=start
/**
* @param {string[]} tokens
* @return {number}
*/
var evalRPN = function(tokens) {
/**
* 逆波兰:后序遍历,我们需要得到正常的表达式(中序遍历,左根右)来计算
* 思路:遇到数字,入栈,遇到符号,我们就弹出两个数字n2,n1,进行计算,再把结果压入栈,之后继续判断是否遇到数字还是符号
*/
// 1 创建栈
const stack = []
// 2 遍历字符串
for(const token of tokens) {
// 3 如果是数字(需要把字符串强制转成数字类型),压入栈
if(!isNaN(Number(token))) {
stack.push(Number(token))
}else {
// 4 不是数字,弹出两个数字,判断符号,再进行运算,结果压入栈,继续判断是否是数字
const n2 = stack.pop()
const n1 = stack.pop()
switch (token) {
case '+':
stack.push(n1 + n2)
break;
case '-':
stack.push(n1 - n2)
break;
case '*':
stack.push(n1 * n2)
break
case '/':
// 取整操作 | 0 保留整数部分
// stack.push(n1 / n2 | 0)
stack.push(parseInt(n1/n2))
break
default:
break;
}
}
}
// 5 直到最后计算完全部,压入的最后一个值,就是最终结果
return stack[0]
};
// @lc code=end
js:isNaN()
JavaScript isNaN() 函数
isNaN()是JavaScript中的一个函数,用于检查一个值是否是非数字NaN(Not a Number)。
语法:
isNaN(value)
参数:
value
:需要检查的值。
返回值:
如果value是NaN,返回true;否则返回false。
示例:
isNaN(123) // false
isNaN('123') // false
isNaN('hello') // true
isNaN('') // false
isNaN(null) // false
isNaN(undefined) // true
isNaN(NaN) // true
注意:如果参数不是数值类型,isNaN()
会尝试将其转换为数值类型,如果无法转换,则返回true。例如,字符串'hello'
无法转换为数值类型,所以isNaN('hello')
返回true。
JavaScript 位运算符 |
JavaScript 运算符 | 菜鸟教程
JavaScript 取整函数_js 取整_不见舟的博客-CSDN博客
javascript位运算技巧(有点错误可在控制台检测)