1. 程式人生 > 實用技巧 >iOS自動化環境搭建(轉載)

iOS自動化環境搭建(轉載)

https://blog.csdn.net/lucky52529/article/details/89155694

單調棧的虛擬碼

stack<int> st;
//此處一般需要給陣列最後新增結束標誌符,具體下面例題會有詳細講解
for (遍歷這個陣列)
{
    if (棧空 || 棧頂元素大於等於當前比較元素)
    {
        入棧;
    }
    else
    {
        while (棧不為空 && 棧頂元素小於當前元素)
        {
            棧頂元素出棧;
            更新結果;
        }
        當前資料入棧;
    }
}

也可以是這樣

單調棧的虛擬碼
先定義棧中是遞增 or 遞減。
for(){   while(){     pop();出棧     資料處理   }   push(i);入棧 }

這個思想來自於

https://www.nowcoder.com/practice/2a2c00e7a88a498693568cef63a4b7bb?tpId=101&&tqId=33256&rp=1&ru=/ta/programmer-code-interview-guide&qru=/ta/programmer-code-interview-guide/question-ranking

題目描述

給定一個可能含有重複值的陣列 arr,找到每一個 i 位置左邊和右邊離 i 位置最近且值比 arr[i] 小的位置。返回所有位置相應的資訊。

輸入描述:

第一行輸入一個數字 n,表示陣列 arr 的長度。
以下一行輸入 n 個數字,表示陣列的值

輸出描述:

輸出n行,每行兩個數字 L 和 R,如果不存在,則值為 -1,下標從 0 開始。
示例1

輸入

複製
7
3 4 1 5 6 2 7

輸出

複製
-1 2
0 2
-1 -1
2 5
3 5
2 -1
5 -1
#include <vector>
#include <iostream>
#include 
<stack> #include <stdio.h> using namespace std; int main() { int n; scanf("%d",&n); vector<int>datas(n); vector<int>left_idx(n,-1); vector<int>right_idx(n,-1); stack<int>st; stack<int>st1; for(int i=0;i<n; i++){ scanf("%d",&datas[i]); } for(int i=0; i<n; i++){ while(!st.empty()&& datas[st.top()]>= datas[i]){ st.pop(); } if(!st.empty()){ left_idx[i] = st.top(); } st.push(i); } for(int i=n-1;i>=0;i--){ while(!st1.empty()&& datas[st1.top()]>= datas[i]){ st1.pop(); } if(!st1.empty()){ right_idx[i] = st1.top(); } st1.push(i); } for(int i=0;i<n;i++){ printf("%d %d\n", left_idx[i], right_idx[i]); } return 0; }
View Code

針對這個問題:

單調棧的應用我們直接拿一些具體的題來對照應用:
1.視野總和

描敘:有n個人站隊,所有的人全部向右看,個子高的可以看到個子低的髮型,給出每個人的身高,問所有人能看到其他人發現總和是多少。
輸入:4 3 7 1
輸出:2
解釋:個子為4的可以看到個子為3的髮型,個子為7可以看到個子為1的身高,所以1+1=2

#include<stdio.h>
#include <iostream>
#include<fstream>
#include <stack>
#include<vector>
#include<limits.h>
using namespace std;
int fieldSum1(vector<int>&v);
int fieldSum2(vector<int>&v);


int main(){

int a[]={4,3,7,1};
vector<int> test(a,a+4);
cout<<fieldSum1(test)<<endl;
cout<<"-------"<<endl;
cout<<fieldSum2(test)<<endl;
cout<<"end"<<endl;
return 0;

}

int fieldSum1(vector<int>&v){
    
    stack<int>st;
    int sum=0;
    v.push_back(INI_MAX);
    for(int i=0; i<v.size();i++){
    
        while(!st.empty() && v[st.top()] < v[i]){
            int idx = st.top();
            sum += (i-1-idx);
            st.pop();
            
        }
        st.push(i);
    }
    
return sum;    
}


int fieldSum2(vector<int>& v)
{
    
    v.push_back(INI_MAX);
    
    stack<int> st;
    int sum = 0;
    for (int i = 0; i < (int)v.size(); i++)
    {
        if (st.empty() || v[st.top()] > v[i])//小於棧頂元素入棧
        {
            st.push(i);
        }
        else
        {
            while (!st.empty() && v[st.top()] <= v[i])
            {
                int top = st.top();//取出棧頂元素
                st.pop();
                sum += (i - top - 1);//這裡需要多減一個1
            }
            st.push(i);
        }
    }
    return sum;
}