class Solution {
public int candy(int[] ratings) {
int n = ratings.length;
int ret = 1; //用于记录答案
//pre用于记录前一个同学分得的糖果数量
int inc = 1, dec = 0, pre = 1;
for (int i = 1; i < n; i++) {
if(ratings[i] >= ratings[i-1]){
//处于递增序列中
dec = 0; //递减序列长度在递增序列中始终为0
pre = ratings[i] == ratings[i- 1] ? 1 : pre+1; //当前同学和上一个同学分数相等时,直接分配1个就行,这样满足最小
ret += pre;
inc = pre; //inc用于记录上一个递增序列的长度
}else {
//处于递减序列中
dec++;
if(dec == inc){
//当递减序列长度和递增序列长度相等时,把递增序列的最后一个同学分配到递减序列中
dec++;
}
ret += dec; //这里加的dec相当于把递减序列翻转后加的每个同学的糖果数量
pre = 1; //pre在递减序列中没有意义,因为我肯定比前一个同学少;
}
}
return ret;
}
}
这里记录这些递增和递减序列是为了更好的加糖果,这里加糖果,相当于所有的递增序列的人都加一个糖果,递减就也是如此。
时间复杂度为O(n),遍历一遍,
char* removeDuplicateLetters(char* s) {
int nums[26], len = strlen(s), vis[26];
memset(nums, 0, sizeof(nums));
memset(vis, 0, sizeof(vis));
char* p = (char*)malloc(sizeof(char) * 27);
for (int i = 0; i < len; i++) {
nums[s[i] - 'a']++;
}
int Top = 0;
for (int i = 0; i < len; i++)
{
if (!vis[s[i] - 'a'])
{
while (Top > 0 && p[Top - 1] > s[i])
{
if (nums[p[Top - 1] - 'a'] > 0)
{
vis[p[--Top] - 'a'] = 0;
} else
break;
}
vis[s[i] - 'a'] = 1;
p[Top++] = s[i];
}
nums[s[i] - 'a'] -= 1;
}
p[Top] = '\0';
return p;
}
在考虑字符 s[i] 时,如果它已经存在于栈中,则不能加入字符 s[i]。为此,需要记录每个字符是否出现在栈中。
在弹出栈顶字符时,如果字符串在后面的位置上再也没有这一字符,则不能弹出栈顶字符。为此,需要记录每个字符的剩余数量,当这个值为 0 时,就不能弹出栈顶字符了。