贪心
柠檬水找零
在柠檬水摊上,每一杯柠檬水的售价为 5 元。
顾客排队购买你的产品一次购买一杯。
每位顾客只买一杯柠檬水,然后向你付 5 元、10 元或 20 元。你必须给每个顾客正确找零,也就是说净交易是每位顾客向你支付 5 元。
注意:一开始你手头没有任何零钱。
如果你能给每位顾客正确找零,返回 true ,否则返回 false 。
代码
int five=0,ten=0,twenty=0;
int a[5]={5,5,5,10,20}; // 顾客付的钱
int i;
for(i=0;i<5;i++) {
if(a[i]==5){
five++; // 直接收下
}
if(a[i]==10){
if(five<=0){ // 5元不够就false
return false;
}
ten++; // 十元加一张
five--; // 五元减一张
}
if(a[i]==20){
if(five>0&&ten>0){ // 先考虑有没有一张十元和一张五元
five--;
ten--;
twenty++;
}else if(five>=3){ // 再考虑有没有三张五元
five-=3;
}else
return false;
}
}
return true;
栈与队列
有效的括号
给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。
代码:
char ch[100],s[100];//ch数组用来匹配,s数组用来读入括号
int j=-1;
scanf("%s",s);
int i=0,len=0;
while(s[i]){
i++;
len++;
}
if(len%2==1){ //判断括号数量,如果为奇数那么必不会匹配(剪枝操作)
return false;
}
for(i=0;i<len;i++){
if(ch[i]=='('){
ch[++j]==')';
}
else if(ch[i]=='['){
ch[++j]==']';
}
else if(ch[i]=='{'){
ch[++j]=='}';
}
else if(ch[i]!=ch[j]){
return false;
}
else if(ch[i]==ch[j]){ // 直接让左括号变为右括号方便判断
j--;
}
}
if(j>=0){ // 下标j不为-1说明数组不为空
return false;
}
else return true;
删除字符串中的所有相邻重复项
给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。
在 S 上反复执行重复项删除操作,直到无法继续删除。
在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。
输入:"abbaca"
输出:"ca"
代码:
char s[100],ch[100]; // 数组ch为栈
scanf("%s",&s);
int len=0,i=0;
while(s[i]){
i++;
len++;
} // 计算字符串长度
int head=0; // head指向栈顶
for(i=0;i<len;i++){ // 时间复杂度O(n)
if(head>0&&ch[head-1]==s[i]){
head--;
}
else{
ch[head++]=s[i];
}
}
ch[head]='\0';
滑动窗口最值:
给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
返回滑动窗口中的最大值。
代码:
int nums[9]={0,1,3,-1,-3,5,3,2,1},k=3; // 初始化nums数组和k
int arr[10]={0}; // 定义单调队列
int h=1,t=0; // h为头下标,t为尾下标
int i;
for(i=1;i<=n;i++){
while(h>=t&&nums[arr[t]]<=nums[i]){ // 当队列有元素且尾元素大小小于当前指向元素大小
t--; // 将较小元素移除队列,保证队列始终为较大元素
}
q[++t]=i; // 将当前元素加入队列
if(q[h]<i-k+1){ // 当头指针元素不在滑动窗口内时
h++; // 将头指针元素移除
}
if(i>=k){
printf("%d",nums[arr[h]]); // 输出最大值
}
}