單調棧 leetcode整理(一)

目錄

    • 單調棧知識
    • 402. 移掉K位數字
    • 1673. 找出最具競爭力的子序列
    • 316. 去除重復字母(1081. 不同字符的最小子序列)
    • 321. 拼接最大數

單調棧知識

單調棧就是一個內部元素有序的棧(大->小 or 小->大),但是只用到它的一端。
核心代碼:摘自C++ | 圖解算法 | 這個單調棧不一般!

insert x
while (!sta.empty() && sta.top()<x)sta.pop()
sta.push(x)

單調棧只能在棧頂操作.
單調棧可以解決的問題:
1、找到一個序列的字典序最小的序列(序列元素位置不可移動)
2、最基礎的應用就是給定一組數,針對每個數,尋找它和它右邊第一個比它大的數之間有多少個數。
3、給定一序列,尋找某一子序列,使得子序列中的最小值乘以子序列的長度最大。
4、給定一序列,尋找某一子序列,使得子序列中的最小值乘以子序列所有元素和最大。

參考有關文章:
一招吃遍力扣四道題,媽媽再也不用擔心我被套路啦~
單調棧的介紹以及一些基本性質
下面是刷題代碼:

402. 移掉K位數字

402. 移掉K位數字

class Solution {
public:string removeKdigits(string num, int k) {vector<char> st;string result;for(int i = 0; i < num.size(); i++){while(st.size() > 0 && st.back() > num[i] && k > 0){st.pop_back();k--;}//否則,進行st.push_back(num[i]);}//考慮到所有情況之后,還有k剩余,但是此時字符是單調遞減的,需要將末尾的字符進行去除while(k > 0){st.pop_back();k--;}//去除前導0int j;for(j=0; j < st.size(); j++){if(st[j] != '0') break;}for(int i = j; i < st.size() ; i++){result += st[i];}//如果最后結果為空,返回0即可if(result.size() == 0) return "0";return result;}
};

1673. 找出最具競爭力的子序列

1673. 找出最具競爭力的子序列

class Solution {
public:vector<int> mostCompetitive(vector<int>& nums, int k) {vector<int> st;int remain = nums.size() - k;for(int i = 0; i < nums.size(); i++){while(st.size() > 0 && st.back() > nums[i] && remain > 0){st.pop_back();remain--;}//否則,進行st.push_back(nums[i]);}while(remain > 0){st.pop_back();remain--;}return st;}
};

316. 去除重復字母(1081. 不同字符的最小子序列)

316. 去除重復字母
錯誤代碼,沒考慮包含text中所有不同的字符一次。
所以出現結果只是不含相同字符的字典序最小的子序列

class Solution {
public:string smallestSubsequence(string s) {vector<char > st;int hash[26]={0};for(int i = 0; i < s.size(); i++){//如果元素大于棧頂元素,并且這個元素沒有出現過,則插入if(st.size() == 0 || (st.back() < s[i] && hash[s[i]-'a'] == 0)){st.push_back(s[i]);hash[s[i]-'a'] = 1;//cout << st.back() <<endl;}else{//如果這個元素小于棧頂元素,并且這個元素沒有出現過,那么我們就刪除棧頂元素,插入這個元素while(st.size() > 0 && s[i] < st.back() && hash[s[i]-'a'] == 0){//被刪除的棧頂元素對應的hash也需要清除hash[st.back()-'a'] = 0;st.pop_back();//cout << st.back() <<endl;}st.push_back(s[i]);hash[s[i]-'a'] = 1;}//如果這個元素已經出現過了,那么不做任何操作}string result;//將vector元素轉化為stringfor(int i = 0; i < st.size(); i++){result += st[i];}return result;}
};

正確代碼:

class Solution {
public:string smallestSubsequence(string s) {vector<char > st;int hash[26]={0};int cnt_s[26]={0};for(int i = 0; i < s.size() ; i++){cnt_s[s[i] - 'a'] += 1;}for(int i = 0; i < s.size(); i++){cnt_s[s[i] - 'a'] -= 1;if(hash[s[i] - 'a'] == 1) continue;while(st.size() > 0){if(st.back() > s[i] && cnt_s[st.back() - 'a'] > 0){hash[st.back() - 'a'] = 0;st.pop_back();}elsebreak;}st.push_back(s[i]);hash[s[i] - 'a'] = 1;}string result;//將vector元素轉化為stringfor(int i = 0; i < st.size(); i++){result += st[i];}return result;}
};

321. 拼接最大數

321. 拼接最大數
1、將k拆分為x,y,格子找nums1,nums2對應的x,y長度的最有競爭力的子序列(如果x,y大于任意數組長度,則pass這個解法)
2、對x+y=k的對應的兩個子序列進行合并
3、對合并后的每個子序列,進行比較,找到最終結果.
4、補充一下比較的規則,從序列的第一個開始比較,返回對應位的較小的序列。
5、合并的規則也需要注意,并不能用簡單的雙指針比較,需要注意到當前數相同的情況,還要往后比較,才能選擇出我們我們送入的數
哪個大取哪個,當前位置相同就繼續比較下一位。這個比較的過程和比較函數有重復的操作,所以我們需要將比較函數做一下修改,保證在合并比較的時候也能使用。

compare函數從兩個index開始對比,如果nums1順位大于nums2,返回值大于0。
有個序列是另一個序列的子序列,這時我們選擇較長的序列。

int compare(vector<int>& nums1,int index1, vector<int>& nums2,int index2){int n = nums1.size();int m = nums2.size();while(index1 < n && index2 < m){int difference = nums1[index1] - nums2[index2];//如果不相同,返回nums1與nums2的差值if (difference != 0) {return difference;}//如果相同,比較下一位index1++;index2++;}//如果比較到這個時候還沒結果,說明有個序列是另一個序列的子序列,這時我們選擇較長的序列return (n - index1) - (m - index2);}

合并函數
每次將順位比較中較大的nums中對應的index送入result數組中。

    vector<int> merge(vector<int>& nums1, vector<int>& nums2){int x = nums1.size();int y = nums2.size();vector<int> result(x + y,0);int index1 = 0, index2 = 0;if(x == 0) return nums2;else if( y == 0) return nums1;//此時需要進行比較,從頭開始比較for(int i = 0; i < x + y; i++){if(compare(nums1,index1,nums2,index2) > 0){result[i] = nums1[index1];index1++;}else{result[i] = nums2[index2];index2++;}}return result;}

最終代碼:

class Solution {
private://function1:找出最具競爭力的子序列/*給你一個整數數組 nums 和一個正整數 k ,返回長度為 k 且最具 競爭力 的 nums 子序列。*/vector<int> mostCompetitive(vector<int>& nums, int k) {vector<int> st;int remain = nums.size() - k;for(int i = 0; i < nums.size(); i++){while(st.size() > 0 && st.back() < nums[i] && remain > 0){st.pop_back();remain--;}//否則,進行st.push_back(nums[i]);}while(remain > 0){st.pop_back();remain--;}return st;}vector<int> merge(vector<int>& nums1, vector<int>& nums2){int x = nums1.size();int y = nums2.size();vector<int> result(x + y,0);int index1 = 0, index2 = 0;if(x == 0) return nums2;else if( y == 0) return nums1;//此時需要進行比較,從頭開始比較for(int i = 0; i < x + y; i++){if(compare(nums1,index1,nums2,index2) > 0){result[i] = nums1[index1];index1++;}else{result[i] = nums2[index2];index2++;}}return result;}int compare(vector<int>& nums1,int index1, vector<int>& nums2,int index2){int n = nums1.size();int m = nums2.size();while(index1 < n && index2 < m){int difference = nums1[index1] - nums2[index2];//如果不相同,返回nums1與nums2的差值if (difference != 0) {return difference;}//如果相同,比較下一位index1++;index2++;}//如果比較到這個時候還沒結果,說明有個序列是另一個序列的子序列,這時我們選擇較長的序列return (n - index1) - (m - index2);}
public:vector<int> maxNumber(vector<int>& nums1, vector<int>& nums2, int k) {int n = nums1.size();int m = nums2.size();//用來放最終結果vector<int> maxSubsequence(k,0);vector<int> cur_maxSubsequence(k,0);//【1】將k拆分為x,y,格子找nums1,nums2對應的x,y長度的最有競爭力的子序列for(int x = 0; x <= n; x++){int y = k - x;//如果x,y大于任意數組長度,則pass這個解法)if(y > m || y < 0 || x < 0 || x > n) continue;vector<int> maxSubsequence1 = mostCompetitive(nums1,x);vector<int> maxSubsequence2 = mostCompetitive(nums2,y);//【2】對x+y=k的對應的兩個子序列進行合并cur_maxSubsequence = merge(maxSubsequence1,maxSubsequence2);//【3】if(compare(cur_maxSubsequence,0,maxSubsequence,0) > 0)maxSubsequence = cur_maxSubsequence;}return maxSubsequence;}
};

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/377583.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/377583.shtml
英文地址,請注明出處:http://en.pswp.cn/news/377583.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

數字簽名 那些密碼技術_密碼學中的數字簽名

數字簽名 那些密碼技術A signature is usually used to bind signatory to the message. The digital signature is thus a technique that binds a person or the entity to the digital data. This binding ensures that the person sending the data is solely responsible …

七、torch.nn

一、神經網絡模塊 進入到PyTorch的torch.nnAPI學習頁面 PyTorch提供了很多的神經網絡方面的模塊&#xff0c;NN就是Neural Networks的簡稱 二、Containers torch.nn下的Containers 一共有六個模塊&#xff0c;最常用的就是Module模塊&#xff0c;看解釋可以知道&#xff0c…

Java多線程初學者指南(8):從線程返回數據的兩種方法

本文介紹學習Java多線程中需要學習的從線程返回數據的兩種方法。從線程中返回數據和向線程傳遞數據類似。也可以通過類成員以及回調函數來返回數據。原文鏈接 從線程中返回數據和向線程傳遞數據類似。也可以通過類成員以及回調函數來返回數據。但類成員在返回數據和傳遞數據時有…

【C++進階】 遵循TDD原則,實現平面向量類(Vec2D)

目錄1、明確要實現的類的方法以及成員函數2、假設已經編寫Vec2D&#xff0c;根據要求&#xff0c;寫出測試代碼3、編寫平面向量類Vec2D,并進行測試4、完整代碼5、最終結果1、明確要實現的類的方法以及成員函數 考慮到效率問題&#xff0c;我們一般將函數的參數設置為引用類型。…

Keilc的中斷號計算方法

中斷號碼 (中斷向量-3)/8轉載于:https://www.cnblogs.com/yuqilihualuo/p/3423634.html

md5模式 簽名_MD的完整形式是什么?

md5模式 簽名醫師&#xff1a;醫學博士/常務董事 (MD: Doctor of Medicine / Managing Director) 1)醫學博士&#xff1a;醫學博士 (1) MD: Doctor of Medicine) MD is an abbreviation of a Doctor of Medicine degree. In the field of Medicine, it is the main academic de…

八、卷積層

一、Conv2d torch.nn.Conv2d官網文檔 torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride1, padding0, dilation1, groups1, biasTrue, padding_modezeros, deviceNone, dtypeNone) 參數解釋官網詳情說明in_channels輸入的通道數&#xff0c;如果是彩色照片通道…

HTMl5結構元素:header

頁眉header 頁眉將是頁面加載的第一個元素&#xff0c;包含了站點的標題、logo、網站導航等。<header> <div class"container_16"> <div class"logo"> <h1><a href"index.html"><strong>Real</st…

【C++grammar】左值、右值和將亡值

目錄C03的左值和右值C11的左值和右值將亡值在C03中就有相關的概念 C03的左值和右值 通俗的理解&#xff1a; (1) 能放在等號左邊的是lvalue (2) 只能放在等號右邊的是rvalue (3) lvalue可以作為rvalue使用 對于第三點可以舉個例子&#xff1a; int x ; x 6; //x是左值&#…

scala字符串的拉鏈操作_在Scala中對字符串進行操作

scala字符串的拉鏈操作Scala字符串操作 (Scala strings operation) A string is a very important datatype in Scala. This is why there are a lot of operations that can be done on the string object. Since the regular operations like addition, subtraction is not v…

九、池化層

一、Pooling layers Pooling layers官網文檔 MaxPool最大池化層下采樣 MaxUnpool最大池化層上采樣 AvgPool最大池化層平均采樣 例如&#xff1a;池化核為(3,3)&#xff0c;輸入圖像為(5,5)&#xff0c;步長為1&#xff0c;不加邊 最大池化就是選出在池化核為單位圖像中的最大…

[分享]SharePoint移動設備解決方案

老外寫的一個PPT&#xff0c;講SharePoint在移動領域的應用&#xff0c;2012年最新的&#xff0c;有iPad喲。/Files/zhaojunqi/SharePoint2010andMobileDevices.pdf 轉載于:https://www.cnblogs.com/zhaojunqi/archive/2012/04/12/2444712.html

十、非線性激活函數

一、ReLU torch.nn.ReLU(inplaceFalse)官網提供的API 其中inplace表示是否在對原始數據進行替換 由函數圖可以看出&#xff0c;負數通過ReLU之后會變成0&#xff0c;正數則不發生變化 例如&#xff1a;input -1&#xff0c;若inplace True&#xff0c;表示對原始輸入數據進…

最短公共子序列_最短公共超序列

最短公共子序列Problem statement: 問題陳述&#xff1a; Given two strings, you have to find the shortest common super sequence between them and print the length of the super sequence. 給定兩個字符串&#xff0c;您必須找到它們之間最短的公共超級序列&#xff0c…

單調棧 leetcode整理(二)

目錄為什么單調棧的時間復雜度是O(n)496. 下一個更大元素 I方法一&#xff1a;暴力方法二:單調棧哈希表739. 每日溫度單調棧模版解優化503. 下一個更大元素 II單調棧循環遍歷為什么單調棧的時間復雜度是O(n) 盡管for 循環里面還有while 循環&#xff0c;但是里面的while最多執…

Android中引入第三方Jar包的方法(java.lang.NoClassDefFoundError解決辦法)

ZZ&#xff1a;http://www.blogjava.net/anchor110/articles/355699.html1、在工程下新建lib文件夾&#xff0c;將需要的第三方包拷貝進來。2、將引用的第三方包&#xff0c;添加進工作的build path。3、&#xff08;關鍵的一步&#xff09;將lib設為源文件夾。如果不設置&…

QTP自傳之web常用對象

隨著科技的進步&#xff0c;“下載-安裝-運行”這經典的三步曲已離我們遠去。web應用的高速發展&#xff0c;改變了我們的思維和生活習慣&#xff0c;同時也使web方面的自動化測試越來越重要。今天&#xff0c;介紹一下我對web對象的識別&#xff0c;為以后的對象庫編程打下基礎…

leetcode中使用c++需要注意的點以及各類容器的初始化、常用成員函數

目錄1、傳引用2、vector使用初始化方法常用成員函數3、字符串string初始化方法常用成員函數4、哈希表 unordered_map初始化常用成員函數示例&#xff1a;計數器5、哈希集合 unordered_set初始化常用成員函數6、隊列 queue初始化成員函數7、棧stack初始化常用成員函數7、emplace…

Linq list 排序,Dictionary 排序

C# 對List成員排序的簡單方法 http://blog.csdn.net/wanzhuan2010/article/details/6205884 LINQ之路系列博客導航 http://www.cnblogs.com/lifepoem/archive/2011/12/16/2288017.html 用一句Linq把一個集合的屬性值根據條件改了&#xff0c;其他值不變 list去重 list.Where((x…

javascript Ajax 同步請求與異步請求的問題

先來看以下代碼&#xff1a; var flagtrue; var index0; $.ajax({url: "http://www.baidu.com/",success: function(data){flagfalse;} }); while(flag){index; } alert(index); 請問最后alert的index的結果是多少&#xff1f; 可能有人會說0唄。實際上卻沒那么簡單…