leetcode 3170. 删除星号以后字典序最小的字符串 中等
给你一个字符串 s
。它可能包含任意数量的 '*'
字符。你的任务是删除所有的 '*'
字符。
当字符串还存在至少一个 '*'
字符时,你可以执行以下操作:
- 删除最左边的
'*'
字符,同时删除该星号字符左边一个字典序 最小 的字符。如果有多个字典序最小的字符,你可以删除它们中的任意一个。
请你返回删除所有 '*'
字符以后,剩余字符连接而成的 字典序最小 的字符串。
示例 1:
输入:s = "aaba*"
输出:"aab"
解释:
删除 '*'
号和它左边的其中一个 'a'
字符。如果我们选择删除 s[3]
,s
字典序最小。
示例 2:
输入:s = "abc"
输出:"abc"
解释:
字符串中没有 '*'
字符。
提示:
1 <= s.length <= 10^5
s
只含有小写英文字母和'*'
字符。- 输入保证操作可以删除所有的
'*'
字符。
分析:用一个长度为 26 的 vector 数组,记录每个对应字符出现的位置,并用 index 记录当前出现的字典序最小的字符的下标,用与字符串 s 等长的 flag 数组记录对应位置是否被删除。遍历 s,如果是字符,则对应下标的 vector 记录这个位置; 如果是 *,则将 vector 数组的 index 位置的最后一个位置去除,flag 对应位置标记 1.遍历完数组后,将所有 flag 为 0 的位置拼接,即可得到答案。
class Solution {
public:string clearStars(string s) {int index=30,flag[100010]={0};vector<int>pos[30];for(int i=0;i<s.length();++i){if(isalpha(s[i]))pos[s[i]-'a'].push_back(i),index=min(index,s[i]-'a');else{flag[i]=1;flag[pos[index][pos[index].size()-1]]=1;pos[index].pop_back();while(!pos[index].size()&&index<26)index++;}}string ans;for(int i=0;i<s.length();++i)if(!flag[i])ans+=s[i];return ans;}
};