LeetCode热题100JS(74/100)第十四天|155|394|739|84|215

发布于:2025-03-28 ⋅ 阅读:(33) ⋅ 点赞:(0)

 155. 最小栈

题目链接:​​​​​​​155. 最小栈

难度:中等

刷题状态:1刷

新知识:

解题过程

思考

示例 1:

输入:
["MinStack","push","push","push","getMin","pop","top","getMin"]
[[],[-2],[0],[-3],[],[],[],[]]

输出:
[null,null,null,null,-3,null,0,-2]

解释:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin();   --> 返回 -3.
minStack.pop();
minStack.top();      --> 返回 0.
minStack.getMin();   --> 返回 -2.
用this.items表示数组
题解分析

参考题解链接:​​​​​​​最小栈 (辅助栈法,清晰图解)

手搓答案(无非废话版)


var MinStack = function() {
    this.items=[]
};

/** 
 * @param {number} val
 * @return {void}
 */
MinStack.prototype.push = function(val) {
    this.items.push(val)
};

/**
 * @return {void}
 */
MinStack.prototype.pop = function() {
    this.items.pop()
};

/**
 * @return {number}
 */
MinStack.prototype.top = function() {
    return this.items[this.items.length-1]
};

/**
 * @return {number}
 */
MinStack.prototype.getMin = function() {
    return Math.min(...this.items)
};

/** 
 * Your MinStack object will be instantiated and called as such:
 * var obj = new MinStack()
 * obj.push(val)
 * obj.pop()
 * var param_3 = obj.top()
 * var param_4 = obj.getMin()
 */

总结

 定义各种方法用MinStack.prototype.

 ​​​​​​​394. 字符串解码

题目链接:​​​​​​​​​​​​​​394. 字符串解码

难度:中等

刷题状态:1刷

新知识:

解题过程

思考

示例 1:

输入:s = "3[a]2[bc]"
输出:"aaabcbc"
题解分析

参考题解链接:​​​​​​​​​​​​​​字符串解码(辅助栈法 / 递归法,清晰图解)

详细分析如下

/**
 * @param {string} s
 * @return {string}
 */
var decodeString = function(s) {
    let arr=[],res='',sum=0
    for(let c of s){
        if(c=='['){
            arr.push([sum,res])
            res='',sum=0
        }else if(c==']'){
            //顶层弹出上一组数据
            let [curSum,lastRes]=arr.pop()
            res=lastRes+res.repeat(curSum)
        }else if(c>='0'&&c<='9'){
            sum+=sum*10+parseInt(c,10)
        }else{
            res+=c
        }
    }
    return res
};

手搓答案(无非废话版)

/**
 * @param {string} s
 * @return {string}
 */
var decodeString = function(s) {
    let res='',arr=[],sum=0
    for(let c of s){
        if(c>='0'&&c<='9'){
            sum=sum*10+parseInt(c,10)
        }else if(c=='['){
            arr.push([res,sum])
            res='',sum=0
        }else if(c==']'){
            let [lastRes,curSum]=arr.pop()
            res=lastRes+res.repeat(curSum)
        }else{
            res+=c
        }
    }
    return res
};

总结

 注意sum的计算方法,0也包含在里面

 ​​​​​​​739. 每日温度

题目链接:​​​​​​​​​​​​​​​​​​​​​739. 每日温度

难度:中等

刷题状态:1刷

新知识:

解题过程

思考

示例 1:

输入: temperatures = [73,74,75,71,69,72,76,73]
输出: [1,1,4,2,1,1,0,0]

用嵌套循环能做出来但会超时,看答案

题解分析

参考题解链接:​​​​​​​​​​​​​​LeetCode 图解 | 739.每日温度

详细分析如下

/**
 * @param {number[]} temperatures
 * @return {number[]}
 */
var dailyTemperatures = function(temperatures) {
    let n=temperatures.length
    let res=Array(n).fill(0)
    let arr=[]
    for(let i=0;i<n;i++){
        let c=temperatures[i]
        while(arr.length>0&&c>temperatures[arr[arr.length-1]]){
            //arr存在
            //比较当前遍历到的温度c 与栈顶索引对应的温度。
            //如果当前温度高于栈顶索引对应的温度,就意味着找到了栈顶索引对应的那一天之后更高温度的天数。
            let t=arr.pop()
            res[t]=i-t
        }
        arr.push(i)
    }
    return res
};

手搓答案(无非废话版)

/**
 * @param {number[]} temperatures
 * @return {number[]}
 */

 var dailyTemperatures=function(temperatures){
    let n=temperatures.length
    let res=Array(n).fill(0),arr=[]
    for(let i=0;i<n;i++){
        let c=temperatures[i]
        while(arr.length&&c>temperatures[arr[arr.length-1]]){
            let t=arr.pop()
            res[t]=i-t
        }
        arr.push(i)
    }
    return res
 }

总结

 注意res[t]=i-t,这里计算的是第t天的天数差,同一个i可能对应好几个t

 ​​​​​​​84. 柱状图中最大的矩形

题目链接:​​​​​​​​​​​​​​​​​​​​​84. 柱状图中最大的矩形

难度:困难

刷题状态:1刷

新知识:

解题过程

思考

示例 1:

输入:heights = [2,1,5,6,2,3]
输出:10
解释:最大的矩形为图中红色区域,面积为 10
没思路,看答案
题解分析

参考题解链接:​​​​​​​暴力解法、栈(单调栈、哨兵技巧)

详细分析如下

/**
 * @param {number[]} heights
 * @return {number}
 */
var largestRectangleArea = function(heights) {
    let n=heights.length
    let res=0,arr=[]

    for(let i=0;i<n;i++){
        let c=heights[i]
        // 当栈不为空且当前高度小于栈顶索引对应的高度时
        while(arr.length&&c<heights[arr[arr.length-1]]){
            let curHeight=heights[arr.pop()]
            // 弹出所有与当前高度相同的栈顶元素,以避免重复计算
            while(arr.length&&curHeight==heights[arr[arr.length-1]]){
                arr.pop()
            }
            let curWidth=arr.length?i-arr[arr.length-1]-1:i
            res=Math.max(res,curHeight*curWidth)
        }
        arr.push(i)
    }
    // 处理栈中剩余的元素
    while(arr.length){
        let curHeight=heights[arr.pop()]
        // 弹出所有与当前高度相同的栈顶元素,以避免重复计算
        while(arr.length&&curHeight==heights[arr[arr.length-1]]){
            arr.pop()
        }
        let curWidth=arr.length?n-arr[arr.length-1]-1:n
        res=Math.max(res,curHeight*curWidth)
    }
    return res
};

手搓答案(无非废话版)

/**
 * @param {number[]} heights
 * @return {number}
 */

 var largestRectangleArea=function(heights){
    let n=heights.length
    let res=0,arr=[]
    for(let i=0;i<n;i++){
        let c=heights[i]
        while(arr.length&&c<heights[arr[arr.length-1]]){
            let curHeight=heights[arr.pop()]
            while(arr.length&&curHeight==heights[arr[arr.length-1]]){
                arr.pop()
            }
            let curWidth=arr.length?i-arr[arr.length-1]-1:i
            res=Math.max(res,curHeight*curWidth)
        }
        arr.push(i)
    }

    while(arr.length){
        let curHeight=heights[arr.pop()]
        while(curHeight==heights[arr[arr.length-1]]){
            arr.pop()
        }
        let curWidth=arr.length?n-arr[arr.length-1]-1:n
        res=Math.max(res,curHeight*curWidth)
    }
    return res
 }

总结

 不好理解,多看看题解链接,然后console出来看看数据

 ​​​​​​​215. 数组中的第K个最大元素

题目链接:​​​​​​​​​​​​​​​​​​​​​215. 数组中的第K个最大元素

难度:中等

刷题状态:1刷

新知识:

解题过程

思考

示例 1:

输入: [3,2,1,5,6,4], k = 2
输出: 5

排序解决很简单,要用堆的方法解决问题,试试quicksort快速排序

题解分析

参考题解链接:​​​​​​​​​​​​​​215. 数组中的第 K 个最大元素(分治,清晰图解)

详细分析如下

/**
 * @param {number[]} nums
 * @param {number} k
 * @return {number}
 */
// var findKthLargest = function(nums, k) {
//     nums.sort((a,b)=>b-a)
//     return nums[k-1]
// };

var findKthLargest=function(nums,k){
    function quicksort(left,right){
        //保存初始边界
        let l=left,r=right
        //选择基准值,一般是中间值
        let mid=nums[Math.floor((left+right)/2)]

        while(left<=right){
            //降序排序
            while(nums[left]>mid) left++
            while(nums[right]<mid) right--
            if(left<=right){
                //交换元素
                [nums[left],nums[right]]=[nums[right],nums[left]]
                left++
                right--
            }
        }
        // console.log(nums,left,right)
        //判断是否找到第k大的元素
        //如果k-1在左半部分,递归左半部分
        if(k-1>=l&&k-1<=right){return quicksort(l,right)}
        //如果k-1在右半部分,递归右半部分
        if(k-1>=left&&k-1<=r){return quicksort(left,r)}
        //如果k-1刚好在分区点,返回结果
        return nums[k-1]
    }
    return quicksort(0,nums.length-1)
}

手搓答案(无非废话版)

/**
 * @param {number[]} nums
 * @param {number} k
 * @return {number}
 */
 var findKthLargest=function(nums,k){
    function quicksort(left,right){
        let l=left,r=right
        let mid=nums[Math.floor((left+right)/2)]
        while(left<=right){
            while(nums[left]>mid) left++
            while(nums[right]<mid) right--
            if(left<=right){
                [nums[left],nums[right]]=[nums[right],nums[left]]
                left++,right--
            }
        }
        if(l<=k-1&&k-1<=right) return quicksort(l,right)
        if(left<=k-1&&k-1<=r) return quicksort(left,r)
        return nums[k-1]
    }
    return quicksort(0,nums.length-1)
 }

总结

 注意let mid=nums[Math.floor((left+right)/2)]这里不能写成let mid=Math.floor((left+right)/2),然后后面用nums[mid],因为left,right会影响该值