社区讨论

复杂度为O(k)~O(n+k)的算法

P1106删数问题参与者 5已保存回复 4

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
4 条
当前快照
1 份
快照标识符
@mi6gg1mq
此快照首次捕获于
2025/11/20 04:28
4 个月前
此快照最后确认于
2025/11/20 04:28
4 个月前
查看原帖
思路:如果前数大于后数,则删除前数。
实现:字符数组的前部为升序序列,后部分为未处理序列。
前部最后数与后部首数比较,如果前数小于等于后数,后数移到前数后面。
如果前数大于后数,则删除前数,后数不动。
前后部分都剔除前导0后,依次输出即可。
设n为数字位数,k为删除位数。时间复杂度最好为O(k),最差O(n+k);
代码实现如下:
···c
CPP
#include<stdio.h>
char s[10000002];    
int  k;
int main(){
    scanf("%s%d",s,&k);
    int  i=0,j=1;                            //i-前数下标,j-后数下标 
    while(k>0){
        if(i<0) s[++i]=s[j++];                //如果前部空,后数移一个到前部 
        while(s[i]<=s[j]) s[++i]=s[j++];    //前数小于等于后数,后数移到前部。 
        i--,k--;                            //前数大于后数,删除前数。 
    }                                        //结束时,i指向前部最后一个数,j指向后部第一个数 
    s[i+1]=0;                                //前部变成字符串 
    for(i=0;s[i]=='0';i++);                 //前部串删除前导0    
    if(s[i]==0)    for(;s[j]=='0';j++);         //后部串删除前导0    
    printf("%s%s\n", s+i,s+j);                //输出前部串和后部串 
    return 0;
}
CPP

回复

4 条回复,欢迎继续交流。

正在加载回复...