4-2 删数问题 (30 分)
给定n位正整数a,去掉其中任意k≤n 个数字后,剩下的数字按原次序排列组成一个新的正整数。对于给定的n位正整数a和正整数 k,设计一个算法找出剩下数字组成的新数最小的删数方案。如果数字最前面有0不输出。
输入格式:
第 1 行是1 个正整数 a。第 2 行是正整数k。
输出格式:
输出最小数。
输入样例:
在这里给出一组输入。例如:
178543
4
5001
1
123456
2
109
1
输出样例:
在这里给出相应的输出。例如:
13
1
1234
9
我的代码为
1 #include<iostream>
2 using namespace std;
3 int main()
4 {
5 string b;
6 int k;
7 cin>>b>>k;
8 int tihuan=b.size();
9 for(int i=0;i<k;i++)
10 {
11 for(int j=0;j<tihuan-1;j++)
12 {
13 if(b[j]>b[j+1])
14 {
15 for(int k=j;k<tihuan-1;k++)
16 {
17 b[k]=b[k+1];
18 }
19 break;
20 }
21 }
22 tihuan--;
23 }
24 int j=0;
25 while(b[j]=='0'&&j<tihuan)
26 j++;
27 if(j==tihuan)
28 cout<<'0';
29 else
30 {
31 for(;j<tihuan;j++)
32 cout<<b[j];
33 }
34 return 0;
35 }
这题运用了算法中贪心算法的知识,贪心策略为前面的一个数要小于后面的一个数,若违反这个规定,则将前面的那个大的数给剔除。
在我看来这一题存在的难点有三个
1.寻找本题对应的贪心策略
2.删除所要删除的数后若该串数字的最前面是0的话用什么方法把0去掉最好
3.若删除了所有的数字后,该怎么办
在写代码的过程中,出现了一个大家可能都会犯的小错误
如果像我一样使用了嵌套for循环来从开头寻找要被删除的数字,在删除了那个数字后并将后面的数字提到前面之后一定要加个break来跳出这层for循环,不然的话for循环会继续从已被删除的数字的位置开始继续进行删除数字的循环,而不是重新开始。
时间复杂度为o(k*n的平方) 空间复杂度为o(n)
我对贪心算法的理解就是:贪心算法是一种极端的算法,不像动态规划和分治法那样稳扎稳打,在用贪心算法求解问题时,一定要找准贪心策略(多列几种贪心策略,然后逐一排除选择最好的那一种),找准之后便可做题。