国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

day58 單調棧

這篇具有很好參考價值的文章主要介紹了day58 單調棧。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

單調棧

使用場景:通常是一維數組,要尋找任一個元素的右邊或者左邊第一個比自己大或者小的元素的位置

本質:空間換時間

三個判斷條件
當前遍歷的元素T[i]小于棧頂元素T[st.top()]的情況
當前遍歷的元素T[i]等于棧頂元素T[st.top()]的情況
當前遍歷的元素T[i]大于棧頂元素T[st.top()]的情況

739. 每日溫度

class Solution {
public:
    vector<int> dailyTemperatures(vector<int>& temperatures) {
        stack<int>s;
        vector<int>result(temperatures.size(), 0);
        s.push(0);
        int index = 1;
        while(index < temperatures.size()){
            while(!s.empty() && temperatures[s.top()] < temperatures[index]){
                int temp = s.top();
                s.pop();
                result[temp] = index - temp;
            }
            s.push(index);
            index++;
        }
        return result;
    }
};

496. 下一個更大元素 I
題目: 給你兩個 沒有重復元素 的數組 nums1 和 nums2 ,其中nums1 是 nums2 的子集。
請你找出 nums1 中每個元素在 nums2 中的下一個比其大的值。

思路 : num2作單調棧找下一個大的值,彈出時,判斷是否在num1中出現過,如果出現則進行賦值,鏈接使用unordered_map

class Solution {
public:
    vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
        vector<int>result(nums1.size(), -1);
        unordered_map<int, int>m;
        stack<int>s;
        for(int i=0; i<nums1.size();i++){
            m[nums1[i]] = i;  
        }
        s.push(0);
        int index = 1;
        while(index < nums2.size()){
            while(!s.empty() && nums2[s.top()] < nums2[index]){ //彈出時判斷
                if(m.find(nums2[s.top()]) != m.end()){
                    result[m[nums2[s.top()]]] = nums2[index];
                }
                s.pop();
            }
            s.push(index);
            index++;
        }
        return result;
    }
};

503. 下一個更大元素 II

題目:循環(huán)數組

簡單版: 兩個數組拼接在一起,然后使用單調棧求下一個最大值

class Solution {
public:
    vector<int> nextGreaterElements(vector<int>& nums) {
        int n = nums.size();
        vector<int>result(n , -1);
        for(int i=0; i<n; i++) nums.push_back(nums[i]);
        
        stack<int>s;
        s.push(0);
        for(int i=1; i<nums.size(); i++){
            while(!s.empty() && nums[s.top()] < nums[i]){
                if(s.top()<n){
                    result[s.top()] = nums[i];
                }
                s.pop();
            }
            s.push(i);
        }
        return result;
    }
};

改進版: 不擴充nums,而是在遍歷的過程中模擬走了兩邊nums

class Solution {
public:
    vector<int> nextGreaterElements(vector<int>& nums) {
        int n = nums.size();
        vector<int>result(n , -1);
     
        
        stack<int>s;
        s.push(0);
        for(int i=1; i<n*2; i++){
            while(!s.empty() && nums[s.top()%n] < nums[i%n]){
                if(s.top()<n){
                    result[s.top()] = nums[i%n];
                }
                s.pop();
            }
            s.push(i);
        }
        return result;
    }
};

42. 接雨水

day58 單調棧,算法

  1. 暴力
    思路:如果按照列來計算的話,寬度一定是1了,我們再把每一列的雨水的高度求出來就可以了
    每一列雨水的高度,取決于,該列左側最高的柱子和右側最高的柱子中最矮的那個柱子的高度。

問題:復雜度為O(n^2) 超時

class Solution {
public:
    int trap(vector<int>& height) {
        int sum = 0;
        for(int i=1; i<height.size()-1; i++){
            int left = 0;
            int right = 0;
            for(int j=i; j>=0; j--){
                left = max(left, height[j]);
            }
            for(int j=i; j<height.size(); j++){
                right = max(right, height[j]);
            }
            sum += min(left, right) - height[i];
        }
        return sum;
        
    }
};

2.雙指針改進暴力 空間換時間 提前將左右最高高度算出來

class Solution {
public:
    int trap(vector<int>& height) {
        int sum = 0;
        vector<int>left(height.size(), 0);
        vector<int>right(height.size(), 0);
        int m_left = height[0];
        int m_right = height[height.size()-1];
        
        for(int i=0; i<height.size(); i++){
            m_left = max(m_left, height[i]);
            left[i] = m_left;
        }

        for(int i=height.size()-1; i>=0; i--){
            m_right = max(m_right, height[i]);
            right[i] = m_right;
            
        }

        for(int i=1; i<height.size()-1; i++){
            sum += min(left[i], right[i]) - height[i];
        }
        return sum;
        
    }
};
  1. 雙指針
    day58 單調棧,算法
    思路:
    單調棧是按照行方向來計算雨水
    棧頂和棧頂的下一個元素以及要入棧的元素,三個元素來接水
    雨水高度是 min(凹槽左邊高度, 凹槽右邊高度) - 凹槽底部高度
    水的寬度是 凹槽右邊的下標 - 凹槽左邊的下標 - 1
class Solution {
public:
    int trap(vector<int>& height) {
        stack<int>s;
        int sum = 0;
        s.push(0);
        for(int i=1; i<height.size(); i++){
            while(!s.empty() && height[s.top()] < height[i]){          
                int cur = s.top();
                s.pop();
                if(!s.empty()){  //來避免 棧內[2] 元素3 村水量 0 只要彈出就可以了
                    int h =  min(height[i], height[s.top()]) - height[cur]; 
                    sum += h * (i-s.top()-1);
                }

            }
             s.push(i); 
        }
        return sum;
    }
};

84. 柱狀圖中最大的矩形
題目給定 n 個非負整數,用來表示柱狀圖中各個柱子的高度。每個柱子彼此相鄰,且寬度為 1 。

求在該柱狀圖中,能夠勾勒出來的矩形的最大面積。
day58 單調棧,算法
主體思路:
每一個位置能達到的最大面積取決于它左右兩側小于它的高度位置。
int w = right-left - 1;
int h = heights[i];
sum = max(sum, w*h);

暴力超時

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int sum = 0;
        for(int i=0; i<heights.size(); i++){
            int left = i;
            int right = i;
            while(left >= 0){
                if(heights[left] < heights[i]) break;
                left--;
            }
            while(right < heights.size()){
                if(heights[right] < heights[i]) break;
                right++;
            }
            int w = right-left - 1;
            int h = heights[i];
            sum = max(sum, w*h);
        }
        return sum;
    }
};

雙指針優(yōu)化,空間換時間,提前記錄左右兩側的位置信息沒有數組保存時,需要一個一個跳進行比較。有數組后,那么可以利用之前的比較信息進行跳著比較。
heights[left] >= heights[i]) 時
直接跳到 left[left]指向的位置
注意
left是往左跳 則遍歷順序從左到右
right 向右跳,則右邊的先算,遍歷順序從右向左

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int n = heights.size();
        vector<int>left(n, -1);
        vector<int>right(n, n);

        for(int i=0; i<n; i++){
            int l = i-1;
            while(l>=0 && (heights[l] >= heights[i])) l = left[l];
            left[i] = l; 
          
        }
        for(int i=n-1; i>=0; i--){
            int r = i+1;
            while(r < n && (heights[r] >= heights[i])) r = right[r];
            right[i] =r;
        }

        int sum=0; 
        for(int i=0; i<n; i++){
        sum = max(sum, heights[i] *(right[i]-left[i]-1));
           
        }
        return sum;

    }
};

單調棧:目的找到左右兩側第一個比它小的元素
棧內元素從小到大,
day58 單調棧,算法
當前元素小于棧頂元素時, 當前元素就是右邊界,棧頂元素的下一個元素就是左邊界, w = right - left - 1 h = height[s.top()] sum = max(sum, h*w)
注意兩種情況文章來源地址http://www.zghlxwxcb.cn/news/detail-620937.html

  1. 2 3 4 5 遞增序列沒有機會彈出 所以在最后面加入一個0 —> 2 3 4 5 0
  2. 8 7 6 5 第一個元素沒有左邊界 所以在最前面加入一個0 —> 0 8 7 6 5
class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
       
        heights.push_back(0);
        heights.insert(heights.begin(), 0);
        int n = heights.size();
        stack<int>s;
        s.push(0);
        int sum = 0;
        for(int i=1; i<n; i++){
            if(heights[i] > heights[s.top()]){
                   s.push(i);
            }else if(heights[i] == heights[s.top()]){
                s.pop();
                s.push(i);
            }else{
                while(!s.empty() && (heights[i] < heights[s.top()])){
                       int mid = s.top();
                       s.pop();
                       if(!s.empty()){
                           int left = s.top();
                           int w = i-left-1;
                           int h = heights[mid];
                           sum = max(sum, w*h);
                       }
                      
                   }
                   s.push(i);
               }
           
        }
        return sum;
    }
};

到了這里,關于day58 單調棧的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 力扣算法刷題Day59|單調棧

    力扣題目:# 503.下一個更大元素II? 刷題時長:參考題解后2min 解題方法:單調棧 復雜度分析 時間O(n) 空間O(n) 問題總結 如何解決環(huán)的問題 本題收獲 循環(huán)數組解決方案 思路一:將兩個nums數組拼接在一起,使用單調棧計算出每一個元素的下一個最大值,最后再把結果集即res

    2024年02月13日
    瀏覽(31)
  • DAY40:貪心算法(九)單調遞增的數字(貪心的思路)

    DAY40:貪心算法(九)單調遞增的數字(貪心的思路)

    本題暴力解法也需要看一下,雖然暴力解法超時了,但是這種思路是一種很基礎的思路,需要了解 數字是沒有辦法直接采用下標遍歷的 ,如果 要for循環(huán)遍歷每個位置的數字,需要把數字轉成字符串string 當且僅當每個相鄰位數上的數字 x 和 y 滿足 x = y 時,我們稱這個整數是

    2024年02月12日
    瀏覽(17)
  • 算法訓練day37|貪心算法 part06(LeetCode738.單調遞增的數字)

    題目鏈接???? 給定一個非負整數 N,找出小于或等于 N 的最大的整數,同時這個整數需要滿足其各個位數上的數字是單調遞增。 (當且僅當每個相鄰位數上的數字 x 和 y 滿足 x = y 時,我們稱這個整數是單調遞增的。) 示例 1: 輸入: N = 10 輸出: 9 示例 2: 輸入: N = 1234 輸出:

    2024年02月09日
    瀏覽(22)
  • 算法刷題Day 37 單調遞增的數字+監(jiān)聽二叉樹

    兩個可能經常要用到的函數 字符串轉數字: to_string() 數字轉字符串: stoi() 利用樹后續(xù)遍歷,同時加上狀態(tài)轉移的方法,非常值得反復學習

    2024年02月13日
    瀏覽(22)
  • 算法打卡day32|貪心算法篇06|Leetcode 738.單調遞增的數字、968.監(jiān)控二叉樹

    算法打卡day32|貪心算法篇06|Leetcode 738.單調遞增的數字、968.監(jiān)控二叉樹

    Leetcode 738.單調遞增的數字 題目鏈接:738.單調遞增的數字 ?大佬視頻講解:單調遞增的數字視頻講解 ?個人思路 這個題目就是從例子中找規(guī)律,例如 332,從后往前遍歷,32不是單調遞增將2變?yōu)?,3減1,變成了329,遍歷到2,32不是遞增,將2變?yōu)?,3減1,變成299,符合題目條件,打印

    2024年04月16日
    瀏覽(19)
  • 【LeetCode題目詳解】第八章 貪心算法 part06 738.單調遞增的數字 968.監(jiān)控二叉樹 (day37補)

    【LeetCode題目詳解】第八章 貪心算法 part06 738.單調遞增的數字 968.監(jiān)控二叉樹 (day37補)

    當且僅當每個相鄰位數上的數字? x ?和? y ?滿足? x = y ?時,我們稱這個整數是 單調遞增 的。 給定一個整數 n ,返回 小于或等于 n 的最大數字,且數字呈 單調遞增 。 示例 1: 示例 2: 示例 3: 提示: 0 = n = 109 # 暴力解法 題意很簡單,那么首先想的就是暴力解法了,來我替大家

    2024年02月10日
    瀏覽(20)
  • day58_LayUI

    day58_LayUI

    layui(諧音:類 UI) 是一套開源的Web UI解決方案,采用自身經典的 模塊化 規(guī)范,并遵循原生HTML/CSS/JS的開發(fā)方式, 常適合網頁界面的快速開發(fā) 。layui 區(qū)別于那些基于MVVM 底層的前端框架,它更多是 面向后端開發(fā)者 ,無需涉足前端各種工具,只需面對瀏覽器本身,讓一切所需

    2024年02月11日
    瀏覽(8)
  • day58

    ?739.?每日溫度? ?496.下一個更大元素?I?? ?739.?每日溫度? 今天正式開始單調棧,這是單調棧一篇掃盲題目,也是經典題。 大家可以讀題,思考暴力的解法,然后在看單調棧的解法。?就能感受出單調棧的巧妙 代碼隨想錄 ?496.下一個更大元素?I? 本題和?739.?每日溫度?看

    2024年02月10日
    瀏覽(15)
  • 代碼隨想錄Day58

    昨天因為志愿活動和筆試耽誤了一整天,今天繼續(xù)學習動規(guī)解決子序列問題。 給定字符串 s 和 t ,判斷 s 是否為 t 的子序列。 字符串的一個子序列是原始字符串刪除一些(也可以不刪除)字符而不改變剩余字符相對位置形成的新字符串。(例如,\\\"ace\\\"是\\\"abcde\\\"的一個子序列,

    2023年04月27日
    瀏覽(97)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包