删数问题的理解与分析
1、实践题目
删数问题
2、问题描述
给定n位正整数a,去掉其中任意k(k≤n)个数字后,剩下的数字按原次序排列组成一个新的正整数。对于给定的n位正整数a和正整数 k,设计一个算法找出剩下数字组成的新数最小的删数方案。
输入格式:第 1 行是1 个正整数 a。第 2 行是正整数k。
输出格式:输出最小数。
3、算法描述
本题运用贪心算法求解。
按照从前往后的顺序搜索,若各位数字递增,则删除最后的k位数字;否则删除第一个递减区间的首字符,然后回到串首,再重复删除。
4、具体代码
1 #include <iostream> 2 #include <string.h> 3 using namespace std; 4 int main() 5 { 6 char a[101]; // 表示n位正整数a 7 int k; // k表示要删掉的数字的数量 8 cin>>a>>k; 9 int len,i; // len表示整数a的总位数,i表示第几位数 10 while(k>0){ // 当需要删除的数字大于0 时 11 i = 0; // 从第一位的位数开始 12 len = strlen(a); 13 while(i<len&&a[i]<=a[i+1]) 14 // 在保证不超出总位数且前一位数大于后一位数的情况下 15 i++; // 最后循环结束,得到一个递增的前i位数 16 while(i<len){ 17 // 此时若i小于len,说明出现前一位大于后一位的情况 18 a[i]=a[i+1]; // 那么将后一位小的数字覆盖前一位大的数字 19 i++; 20 } 21 k--; // 需要删除的总数字数减少 22 } 23 i=0; 24 len = strlen(a); 25 while(a[i]=='0'&&i<len) i++; // 防止出现多个0的情况 26 if(i==len) cout<<'0'; // 防止整数a全被删除 27 else { 28 for(i=i;i<len;i++) 29 cout<<a[i]; 30 } 31 return 0; 32 }
5、算法的时间复杂度和空间复杂度
时间复杂度:代码的主要算法部分有两层循环,循环的次数是k*n次,其中k表示要删除的位数,n表示整数a的位数,即时间复杂度为:O(kn)
空间复杂度:算法中定义了一个char型的数组,用来存储整数a的各个位数,即n位数,即空间复杂度为:O(n)
6、心得体会
一开始没理解好题目,结果导致写完后的代码只有样例1过了,其他的样例全部出错。后来经过和队友的讨论以及借鉴了班级大佬的解题思路,最终顺利完成了任务。