题目
设有一个正整数由n位数构成,删除其中的任意k位数后所得到的正整数最大
输入格式
输入要求:输入的第1行为该正整数,第2行为需要删除的位数k
输出格式
输出要求:输出删除k位数之后的最大的正整数。
输入样例
196857 2
输出样例
9857
解题思路
思路一 [ 贪心 ]
1. 每次从高位向低位数比较 [ **从左向右比较** ]- 若**高位数字小**,则删除高位数字- 若**高位数字大**,则继续向后比较2. 从高位向低位依次比较结束,未找到高位小于低位的数字,则**删除末尾数字**- **解释:**比较序列**下标**是从 **0 **开始到 **num.size() - 2** 结束
🍖实例说明
2319274 从高位向低位数比较
K=1 时,2<3 ,删除2,得到 319274**
K=2 时,2<3 ,删除2,得到** 319274**
3>1 ,略过
1<9, 删除1,得到 39274
K=3 时, 2<3 ,删除2,得到** 319274**
3>1 ,略过
1<9 ,删除1,得到 **39274**
3<9 ,删除3,得到** 9274**
**
思路二 [ 动态规划 ]
分析:
1. 假设** str** 为长度为** n **的数字字符串1. **S[i][j] **表示删除 **str[0...i-1] **中** j **个数字后的**最大字符数字**1. 如果删除第** i **个数- 则 **S[i][j] **等于删除前 **i-1 **个字符中的 **j-1 **位的最优解- 即 **S[i][j]=S[i-1][j-1]**4. 如果不删除第 **i **个数- 则** S[i][j]** 等于删除前** i-1 **个字符中** j **位的最优解+str[i]- 即 **S[i][j]=S[i-1][j]+str[i-1]**5. 即 **S[i][j]=max(S[i-1][j-1],S[i-1][j]+str[i-1])**5. 初始状态为当** j=0** 时,不删除任何位的数字,即 **S[i][j]=str[0...i-1]**
状态转移方程如下
时间复杂度:O( n×k )
空间复杂度:O( n×k )
优化:
1. 上述的转移方程** S[i][j]=max(S[i-1][j-1],S[i-1][j]+str[i-1])**1. 可看出在**每次 i 循环**,**只与 i-1 相关**,因此只需要通过一个变量 **last **保存上一次的结果1. 故状态转移方程可以简化为** S[j]=max(last,S[j]+str[i-1])**
解题代码
贪心代码
/**** 参数解释:* i变量 : for循环基础变量* k变量 : 存储要删除的位数个数* num数组 : 用于存放正整数数字****/#include<string>using namespace std;void Delete(string &num,int k) {if (k > num.size())//排除异常输入return;while (k--) {int i ;for (i = 0; i < num.size() - 1; i++) { //依次从左向右检查if (num[i] < num[i + 1]) { //高位数字小于低位数字num.erase(num.begin()+i); //删除 i 下标,即高位数字break;}}if(i== num.size() - 1) //从左向右检查,高位数字均小于低位数字num.erase(num.end()-1); //删除未位数字}if (!num.size()) //数组全删光,置零num.push_back('0'); //🚩注意: num[0]='0' 赋值错误,原因不详}int main(){string num;int k;cin >> num >> k;Delete(num, k);cout << num << endl;system("pause");return 0;}
动态规划代码
#include<string>using namespace std;// dynamic programming// time complexity: O(n*k)// space complexity: O(n*k)string deleteKBits_2(string str,int k){int tlen=str.length();vector<vector<string> > nums(tlen+1,vector<string>(k+1));string s1,s2;for(int i=1;i<=tlen;i++){for(int j=0;j<i && j<=k;j++){if(j==0){nums[i][j]=str.substr(0,i);}else{s1=nums[i-1][j-1];s2=nums[i-1][j]+str[i-1];if(s1.compare(s2)<=0)nums[i][j]=s2;elsenums[i][j]=s1;}}}return nums[tlen][k];}// dynamic programming// time complexity: O(n*k)// space complexity: O(k)string deleteKBits_3(string str,int k){int tlen=str.length();vector<string> nums(k+1);string s1,s2,last;for(int i=1;i<=tlen;i++){for(int j=0;j<i && j<=k;j++){if(j==0){last=nums[j];nums[j]=str.substr(0,i);}else{// s1=lasts1=nums[j-1];s2=nums[j]+str[i-1];if(s1.compare(s2)<=0){last=nums[j];nums[j]=s2;}else{last=nums[j];nums[j]=s1;}}}}return nums[k];}// dynamic programming// time complexity: O(n*k)// space complexity: O(k)string deleteKBits_4(string str,int k){int tlen=str.length();vector<string> nums(k+1);string tmp,s2,last;for(int i=1;i<=tlen;i++){for(int j=0;j<i && j<=k;j++){if(j==0){last=nums[j];nums[j]=str.substr(0,i);}else{// s1=last// s1=nums[j-1];s2=nums[j]+str[i-1];if(last.compare(s2)<=0){last=nums[j];nums[j]=s2;}else{tmp=nums[j];nums[j]=last;last=tmp;}}}}return nums[k];}int main(){string str="2319274";int k=3;cout <<deleteKBits_2(str,k)<< endl;cout <<deleteKBits_3(str,k)<< endl;cout <<deleteKBits_4(str,k)<< endl;system("pause");return 0;}
