代码随想录第49天 | ● 503.下一个更大元素II ● 42. 接雨水

503.下一个更大元素II

/**
 * @param {number[]} nums
 * @return {number[]}
 */
var nextGreaterElements = function(nums) {
    nums=[...nums,...nums]
    console.log(nums)
   const n=nums.length
   const res=Array(n).fill(-1)
   const stack=[]   // 递增栈:用于存储元素右面第一个比他大的元素下标
   stack.push(0)
   for(let i=0;i<n;i++){
       const top=stack[stack.length-1]
    
           while(stack.length && nums[i] > nums[stack[stack.length - 1]]){
               const top=stack.pop()
               res[top]=nums[i]
           }
       stack.push(i);
   }
   return res.slice(0,n/2);
};

第一想法

数组拼接

利用取模做循环数组

/**
 * @param {number[]} nums
 * @return {number[]}
 */
var nextGreaterElements = function(nums) {
   const n=nums.length
   const res=Array(n).fill(-1)
   const stack=[]   // 递增栈:用于存储元素右面第一个比他大的元素下标
   stack.push(0)
   for(let i=0;i<n*2;i++){
       const top=stack[stack.length-1]
    
           while(stack.length && nums[i%n] > nums[stack[stack.length - 1]]){
               const top=stack.pop()
               res[top]=nums[i%n]
           }
       stack.push(i%n);
   }
   return res
};

42. 接雨水

/**
 * @param {number[]} height
 * @return {number}
 */
var trap = function(height) {
// 双指针
//用数组记录左右两边的最高
let  n= height.length
let lm=new Array(n).fill(0)
let rm=new Array(n).fill(0)
lm[0]=height[0]
rm[n-1]=height[n-1]
//记录每根柱子的左右两边的最大值
for(let i=1;i<n;i++){
 lm[i]=Math.max(height[i],lm[i-1])
 rm[n-i-1]=Math.max(height[n-i-1],rm[n-i])
}
// 累加
let sum=0
for(let i=1;i<n;i++){
    sum+=Math.min(lm[i],rm[i])-height[i]
}
return sum
};



//单调栈
var trap = function(height) {
    const len = height.length;
    if(len <= 2) return 0; // 可以不加
    const st = [];// 存着下标,计算的时候用下标对应的柱子高度
    st.push(0);
    let sum = 0;
    for(let i = 1; i < len; i++){ // 只处理的情况三,其实是把情况一和情况二融合了
        while (st.length !== 0 && height[i] > height[st[st.length - 1]]) { // 注意这里是while
            let mid = st[st.length - 1];
            st.pop();
            if (st.length !== 0) {
                let h = Math.min(height[st[st.length - 1]], height[i]) - height[mid];
                let w = i - st[st.length - 1] - 1; // 注意减一,只求中间宽度
                sum += h * w;
            }
        }
        st.push(i);
    }
    return sum;
};

单调

讲解

收获

单调栈就是保持栈内元素有序。和栈与队列:单调队列 (opens new window)一样,需要我们自己维持顺序,没有现成的容器可以用。

通常是一维数组,要寻找任一个元素的右边或者左边第一个比自己大或者小的元素的位置,此时我们就要想到可以用单调栈了。

你可能感兴趣的:(代码随想录,leetcode,javascript,算法)