九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開(kāi)通VIP
單調(diào)棧的經(jīng)典例題
前言
算法中的單調(diào)棧應(yīng)用十分的廣泛;單調(diào)棧簡(jiǎn)單的來(lái)說(shuō)就是棧內(nèi)元素單調(diào)遞增或者單調(diào)遞減的棧,同時(shí)單調(diào)棧還可以不斷的維護(hù)一組某種或多種規(guī)律的數(shù)據(jù),利用這一性質(zhì)可以解決許多算法問(wèn)題。本文主要講解單調(diào)棧的算法用法,需對(duì)單調(diào)棧具有一定的了解。
問(wèn)題描述
問(wèn)題一
給你一個(gè)字符串 s ,一個(gè)整數(shù) k ,一個(gè)字母 letter 以及另一個(gè)整數(shù) repetition 。返回 s 中長(zhǎng)度為 k 且 字典序最小 的子序列,該子序列同時(shí)應(yīng)滿足字母 letter 出現(xiàn) 至少 repetition 次。生成的測(cè)試用例滿足 letter 在 s 中出現(xiàn)至少 repetition 次。
子序列 是由原字符串刪除一些(或不刪除)字符且不改變剩余字符順序得到的剩余字符串。
字符串 a 字典序比字符串 b 小的定義為:在 a 和 b 出現(xiàn)不同字符的第一個(gè)位置上,字符串 a 的字符在字母表中的順序早于字符串 b 的字符。
樣例:
輸入:s = "leetcode", k = 4, letter = "e", repetition= 2
輸出:"ecde"
解釋:"ecde" 是長(zhǎng)度為 4 且滿足字母 "e" 出現(xiàn)至少 2 次的字典序最小的子序列。
題目來(lái)源 力扣:5893. 含特定字母的最小子序列
https://leetcode-cn.com/problems/smallest-k-length-subsequence-with-occurrences-of-a-letter/
題目分析
題意:此題主要描述的是需要維護(hù)一個(gè)長(zhǎng)度為k的字典序最小且至少出現(xiàn)repetition 次letter字母的s的子序列,關(guān)鍵詞就是維護(hù)一個(gè)長(zhǎng)度為k的字典序最小的子序列,子序列中包含至少repetition 個(gè)letter字母;此題的正好符合單調(diào)棧的性質(zhì),利用單調(diào)棧來(lái)維護(hù)以上性質(zhì)!
維護(hù)三種性質(zhì):
性質(zhì)1:維護(hù)字典序單增的字符串。(滿足題意中的字典序最小這一性質(zhì))
性質(zhì)2:維護(hù)長(zhǎng)度為k的字符串。(滿足題中長(zhǎng)度為k的字符串這一性質(zhì))
性質(zhì)3:維護(hù)子序列中包含至少repetition 個(gè)letter字母。(同理滿足題意性質(zhì))
const int N = 50010;
class Solution {
public:
int cnt[N];
string  smallestSubsequence(string s, int k, char letter, int repetition) {
int n = s.size();
for (int i = n-1; i >=  0; i --){
if (s[i] == letter)  cnt[i] = cnt[i + 1] + 1;
else cnt[i] = cnt[i+1];
//cnt[i]統(tǒng)計(jì)在i的右側(cè)還有多少個(gè)letter,便于后續(xù)維護(hù)
}
string ans;
int p = 0; // p用于記錄當(dāng)前維護(hù)字符串中的letter數(shù)量
// 單調(diào)棧模板
for (int i = 0; i < n; i  ++){
char c = s[i];
// 維護(hù)字典序單調(diào)增的字符串
while(!ans.empty()  && c < ans.back()){
// 維護(hù)長(zhǎng)度為不低于k的字符串
if (ans.size() - 1  + n - i < k) break;
if (ans.back() ==  letter){
// 維護(hù)子序列中包含至少repetition  個(gè)letter字母
if (p - 1 +  cnt[i] < repetition) break;
p --;
}
ans.pop_back();
}
if (c == letter) p ++,  cnt[i] --;
ans.push_back(c);
}
// 因?yàn)樽罱K維護(hù)的字符串為長(zhǎng)度不低于k的字符串,其長(zhǎng)度可能超過(guò)k,故此將其長(zhǎng)度縮減至k
while(ans.size() > k) {
if (ans.back() ==  letter) p --;
ans.pop_back();
}
// 在縮減至k的操作過(guò)程中,可能將letter減去,導(dǎo)致字符串中的letter個(gè)數(shù)少于repetition
// 所以如果letter個(gè)數(shù)少于repetition需要將字符串的末尾值換位letter即可滿足
for (int i = ans.size() -  1; i >= 0; i --){
if (p < repetition  && ans[i] != letter) {
ans[i] = letter;
p ++;
}
}
return ans;
}
};
問(wèn)題二
返回 s 字典序最小的子序列,該子序列包含 s 的所有不同字符,且只包含一次。
樣例
輸入:s ="cbacdcbc"
輸出:"acdb"
題目來(lái)源 力扣:1081. 不同字符的最小子序列
https://leetcode-cn.com/problems/smallest-subsequence-of-distinct-characters/
題目分析
此題與上一題類似,求一個(gè)最小字典序的子序列,且子序列的必須包含s中所有不同的字符只包含一次。
維護(hù)二種性質(zhì):
性質(zhì)一:維護(hù)一個(gè)字典序最小的子序列。
性質(zhì)二:維護(hù)包含所有不同字符且只包含一次的子序列。
class Solution {
public:
// cnt記錄在s中從i向右中還存在的多少個(gè)對(duì)應(yīng)字符
int cnt[28];
// snt記錄字符在維護(hù)的字符串中是否存在
bool snt[28];
string  smallestSubsequence(string s) {
string t;
int n = s.size(), k = 0;
for (int i = n-1; i >=  0; i --){
int x = s[i] - 'a';
if (cnt[x] == 0) k ++;
cnt[x] ++;
}
for (int i = 0; i < n; i  ++){
char c = s[i];
int u = c - 'a';
// 維護(hù)最小字典序的子序列
while(!t.empty()  && t.back() > c) {
int x = t.back() -  'a';
// 維護(hù)包含所有不同字符且只包含一次的子序列
if (cnt[x] <= 0  || snt[u]) break;
t.pop_back();
snt[x] = false;
}
if (!snt[u])  t.push_back(c);
snt[u] = true, cnt[u]  --;
}
return t;
}
};
結(jié)語(yǔ)
稿件來(lái)源:深度學(xué)習(xí)與文旅應(yīng)用實(shí)驗(yàn)室(DLETA)
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
面試官,別問(wèn)我 Bit Operation 了!
正則表達(dá)式說(shuō)明
Python支持哪些數(shù)據(jù)類型?六大類!
完美Python入門基礎(chǔ)知識(shí)點(diǎn)總結(jié),看完你的Python就完全入門了!
Python大牛整理最全零基礎(chǔ)入門學(xué)習(xí)資料
python字符串、字符串處理函數(shù)及字符串相關(guān)操作
更多類似文章 >>
生活服務(wù)
熱點(diǎn)新聞
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服