当前位置:网站首页>JS中的栈(含leetcode例题)<持续更新~>
JS中的栈(含leetcode例题)<持续更新~>
2022-06-12 17:58:00 【走出自闭的鸟儿】
文章目录
- 栈(stack)
- 特性
- 实现方式
- leetcode例题
- [20. 有效的括号](https://leetcode.cn/problems/valid-parentheses/)
- [155. 最小栈](https://leetcode.cn/problems/min-stack/)
- [232. 用栈实现队列](https://leetcode.cn/problems/implement-queue-using-stacks/)
- [496. 下一个更大元素 I](https://leetcode.cn/problems/next-greater-element-i/)
- [682. 棒球比赛](https://leetcode.cn/problems/baseball-game/)
- [1021. 删除最外层的括号](https://leetcode.cn/problems/remove-outermost-parentheses/)
- [1047. 删除字符串中的所有相邻重复项](https://leetcode.cn/problems/remove-all-adjacent-duplicates-in-string/)
- [1441. 用栈操作构建数组](https://leetcode.cn/problems/build-an-array-with-stack-operations/)
栈(stack)
特性
先进后出
实现方式
- 基于数组实现
// 封装栈类
function Stack(){
// 栈的属性
this.items = []
// 栈的相关操作
// 1.push压栈
Stack.prototype.push = function(element){
return this.items.push(element)
}
// 2.pop出栈
Stack.prototype.pop = function(){
return this.items.pop()
}
// 3.peek查看栈顶
Stack.prototype.peek = function(){
return this.items[this.items.length - 1]
}
// 4.isEmpty判断栈是否为空
Stack.prototype.isEmpty = function(){
return this.items.length == 0
}
// 5.size获取个数
Stack.prototype.size = function(){
return this.items.length
}
// 6.toString转为字符串
Stack.prototype.toString = function(){
let res = ''
for(let i =0;i<this.items.length;i++){
res += this.items[i]+','
}
return res
}
}
// 7.getMin获取最小值
Stack.prototype.toString = function(){
var min = this.item[0]
for(var i = 1 ;i<this.item.length ; i++){
if(this.item[i]<min){
min = this.item[i]
}
}
return min
}
// 栈的使用
var s = new Stack()
- 基于链表实现
待补充
leetcode例题
20. 有效的括号
**
* @param {
string} s
* @return {
boolean}
*/
var isValid = function(s) {
var isMatch = function(left,right){
if(left==='(' && right===')') return true
if(left==='[' && right===']') return true
if(left==='{' && right==='}') return true
return false
}
const stack = []
const leftMoudle = "([{"
const rightMoudle = "}])"
for(let i = 0 ; i < s.length ; i++){
if(leftMoudle.includes(s[i])){
stack.push(s[i])
}else if(rightMoudle.includes(s[i])){
if(isMatch(stack[stack.length-1],s[i])){
stack.pop()
}else{
return false
}
}
}
if(stack.length === 0){
return true
}else{
return false
}
};
155. 最小栈
// 求最小值的主要思路是
// 创建另一个min_stack只用来比较当前push的最小值和min_stack的栈顶
// 谁小就把谁push进去
// 最后的最小值就是栈顶
var MinStack = function() {
this.item = []
this.min_stack = [Infinity]
};
/** * @param {number} val * @return {void} */
MinStack.prototype.push = function(val) {
if(val<this.min_stack[this.min_stack.length-1]){
this.min_stack.push(val)
}else{
this.min_stack.push(this.min_stack[this.min_stack.length-1])
}
return this.item.push(val)
};
/** * @return {void} */
MinStack.prototype.pop = function() {
this.min_stack.pop()
return this.item.pop()
};
/** * @return {number} */
MinStack.prototype.top = function() {
return this.item[this.item.length-1]
};
/** * @return {number} */
MinStack.prototype.getMin = function() {
return this.min_stack[this.min_stack.length-1]
};
232. 用栈实现队列
// stack1为主栈,代表队列
// stack2辅助
// push功能直接加在stack1
// pop:
// 1.先将stack1出栈,再入栈到stack2中,这样就实现了逆置,再pop掉stack2,实现删除第一个元素。
// 2.此时要注意,删除第一个元素后要再进行一遍将stack2逆置给stack1的操作,避免中间有push使得顺序错乱。
var MyQueue = function() {
this.stack1 = []
this.stack2 = []
};
/** * @param {number} x * @return {void} */
MyQueue.prototype.push = function(x) {
this.stack1.push(x)
};
/** * @return {number} */
MyQueue.prototype.pop = function() {
while(this.stack1.length){
let n = this.stack1.pop()
this.stack2.push(n)
}
const res = this.stack2.pop()
while(this.stack2.length){
let n = this.stack2.pop()
this.stack1.push(n)
}
return res
};
/** * @return {number} */
MyQueue.prototype.peek = function() {
return this.stack1[0]
};
/** * @return {boolean} */
MyQueue.prototype.empty = function() {
if(this.stack1[0]){
return false
}else{
return true
}
};
当然,这种方式复杂度太高,需要优化
496. 下一个更大元素 I
var nextGreaterElement = function(nums1, nums2) {
// Map + Stack
let map = new Map()
let stack = []
let res = []
// 遍历nums2,找到每一个元素的下一个最大元素
// 思路为:循环的元素大于栈顶元素,且栈不为空,即找到下一个最大值,将栈顶元素作为key,下一个作为value
// 存入map,将栈顶元素pop
nums2.forEach(item=>{
while(stack.length && item>stack[stack.length-1]){
map.set(stack.pop(),item)
}
stack.push(item)
})
// 剩余元素没有下一个最大值,value为-1
stack.forEach(item=>map.set(item,-1))
// 遍历nums1,将符合要求的push到结果中
nums1.forEach(item=>res.push(map.get(item)))
return res
};
之后leetcode中遇到求一个更大元素类型的题都是使用map+stack
682. 棒球比赛
// 创建栈,如果默认为数字就直接push进去
// 为C则删除栈顶
// 为D则push栈顶的2倍
// 为+则计算栈顶和栈顶下一个元素之和
// 最后将栈内所有元素求和
var calPoints = function(ops) {
let sum = 0
const stack = []
for(let item of ops){
switch(item){
case 'C':
stack.pop()
break
case 'D':
stack.push(stack[stack.length-1]*2)
break
case '+':
stack.push(stack[stack.length-2]+stack[stack.length-1])
break
default:
stack.push(parseInt(item))
break
}
}
for(let i=0;i<stack.length;i++){
sum = sum + stack[i]
}
return sum
};
1021. 删除最外层的括号
// 理解题目:将整体想成一个栈,遇到左括号入栈、遇到右括号将左括号出栈;当栈为空的时候,代表找到了一次最外层括号
// 实际代码,设置一个计数器,遇到左括号就++,遇到右括号就--
// 遇到左括号,计数器大于1时,代表不是最外层左括号,加入res字符串
// 遇到右括号,计数器大于0时。代表不是最外层右括号,加入res字符串
var removeOuterParentheses = function(s) {
let num = 0
let res = ""
for(let item of s){
if(item=='('){
num++
if(num>1){
res += item
}
}else{
num--
if(num>0){
res += item
}
}
}
return res
};
1047. 删除字符串中的所有相邻重复项
类似于匹配问题,一般都会用到栈
// 遍历字符串写入栈
// 如果当前遍历的字母和栈顶字母相等,代表出现相邻相等,就删除栈顶元素
// 如果不等代表没有出现这种情况,继续写入栈
// 最后栈内的元素就是满足要求的,转为字符串即可
var removeDuplicates = function(s) {
const stack = []
for(let i=0;i<s.length;i++){
if(stack[stack.length-1] == s[i]){
stack.pop()
}else{
stack.push(s[i])
}
}
return stack.join('')
};
1441. 用栈操作构建数组
// 奇奇怪怪的代码增加了
// 因为list是递增的,我就没有使用n,而是自己使用i计数
// 当target数组的最后一个数小于i的时代表已经完成操作
var buildArray = function(target, n) {
const res = []
let i=1
while(target[target.length-1]>=i){
for(let j=0;j<target.length;j++){
if(target[j]==i){
res.push("Push")
i++
}else{
res.push("Push","Pop")
i++
j--
}
}
}
return res
};
边栏推荐
- Introduction to cookie usage
- A method of quickly reusing wechat login authorization in app
- Codeforces Round #398 (Div. 2) D. Cartons of milk
- leetcode 718 最长公共子串
- Click the list page of vant3+ts+pinia tab to enter the details. The tab on the details page is highlighted in the original position, and the refresh highlight is in the first item by default
- App中快速复用微信登录授权的一种方法
- Leetcode 718 longest common substring
- MySQL learning notes
- DRM driven MMAP detailed explanation: (I) preliminary knowledge
- EASYCODE template
猜你喜欢
Hangzhou AI developer meetup registration opens!
WinForm, crystal report making
续2 asp.net core 路由程序基础使用演示0.2 默认控制器数据的获取到
Office application cannot start normally 0xc0000142
Vant3+ts H5 pages are nested into apps to communicate with native apps
LCD parameter interpretation and calculation
C operation database added business data value content case school table
利用小程序快速生成App,只需七步
ESP32-C3 ESP-IDF 配置smartconfig 和 sntp 获取网络时间
Esp-idf adds its own components
随机推荐
New media operation material website sharing enables you to create current affairs with half the effort
Authorization in Golang ProjectUseing Casbin
小程序+App,低成本获客及活跃的一种技术组合思路
channel原创
使用MongoDB官方go库操作MongoDB原创
idea 常用快捷键
Original error interface
error接口原创
Reconnaître l'originalité de la fonction
进阶之大山-asp.net core 路由程序基础使用演示0.1
有源差分晶振原理圖以及LV-PECL、LVDS、HCSL區別
leetcode 718 最长公共子串
利用小程序快速生成App,只需七步
Vant3+ts encapsulates uploader upload image component
轻量、便捷的小程序转App技术方案,实现与微信/流量App互联互通
Use of split method of string
Window版本pytorch入门深度学习环境安装与配置
DRM driven MMAP detailed explanation: (I) preliminary knowledge
系统设计之图状数据模型
在同花顺开户证券安全吗