1. 单调栈(队列)
class Solution {
struct node{
int id;
char ch;
node(int a,char c):id(a),ch(c){}
};
bool compare(node n1,node n2){
return n1.ch > n2.ch;
}
public:
string smallestSubsequence(string s, int k, char letter, int repetition) {
int n = s.size();
vector<int>v(1,0); //表示第i个letter在s中出现的位置
int appear_num = 0; //表示letter出现的次数
for(int i = 0;i<n;i++){
if(s[i] == letter){
appear_num++;
v.push_back(i);
}
}
int other_character_num = k-repetition;
string ret = "";
int start_id = 0;
int end_id = n-1;
deque<node>dq;//相当于一个递增栈,每次从栈底贪心选出当前未知的字母。
for(int i = 1;i<=other_character_num;i++){
//总共有appear_num个letter,那么第1个lette出现的范围应该保证
//1.选了之后还剩repetition-1个letter,如果目前的letter数量不够的话,够了就不管他了
//2.选了之后至少还有k-1个字母
int tmp1 = n-k;
int tmp2 = func(n,appear_num,repetition,v);
//cout<<"tmp1: "<<tmp1<<"tmp2: "<<tmp2<<endl;
end_id = min(tmp1,tmp2);
for(int j = start_id;j<=end_id;j++){
if(dq.empty()){
dq.push_back(node(j,s[j]));
continue;
}
node n2 = node(j,s[j]);
while(!dq.empty()){
node n1 = dq.back();
if(compare(n1,n2)){
dq.pop_back();
}else{
break;
}
}
dq.push_back(n2);
}
node target = dq.front();
dq.pop_front();
char ch = target.ch;
ret += ch;
start_id = end_id+1;
//cout<<"ch:"<<ch<<" start_id:"<<start_id<<" size:"<<dq.size()<<endl;
k--;
if(ch == letter && repetition>0){
repetition--;
i--;
}
}
while(repetition--){
ret += letter;
}
return ret;
}
private:
int func(int n,int appear_num,int repetition,vector<int>& v){
if(repetition<=0){
return n-1;
}else{
return v[appear_num-repetition+1];
}
}
};
2. 哈希表加数学推导(一般适用于等式的数学推导)
3. 动态规划
3.1类型 :柱状图
接雨水1
柱状图中最大矩形,本题也可以用单调栈,需要分析一下。
4.bitset的使用
5.双指针
适合于求连续区间的长度的问题,即窗口大小问题。
考试最大困扰度