(笔试题)删除K位数字
题目:
现有一个 n 位数,你需要删除其中的 k 位,请问如何删除才能使得剩下的数最大?
比如当数为 2319274, k=1 时,删去 2 变成 319274 后是可能的最大值。
思路:
1、贪心算法
每次从高位向低位数,删除高位数字比低位数字小的那位数字。如2319274
第一次2<3,删除2,得到319274
第二次3>1,略过,1<9,删除1,得到39274
第三次3<9,删除3,得到9274
。。。。。。
// greedy method
string deleteKBits_1(string str,int k){int tlen=str.length();bool flag=true;int len;while(k && flag){len=str.length();for(int i=0;i<len-1;i++){if(str[i]<str[i+1]){str.erase(i,1);flag=true;break;}}k--;}return str.substr(0,tlen-k);
}
2、动态规划
分析:
假设str为长度为n的数字字符串,S[i][j]表示删除str[0...i-1]中j个数字后的最大字符数字。
如果删除第i个数,则S[i][j]等于删除前i-1个字符中的j-1位的最优解,即S[i][j]=S[i-1][j-1];
如果不删除第i个数,则S[i][j]等于删除前i-1个字符中j位的最优解+str[i],即S[i][j]=S[i-1][j]+str[i-1];
即S[i][j]=max(S[i-1][j-1],S[i-1][j]+str[i-1])
初始状态为当j=0时,不删除任何位的数字,即S[i][j]=str[0...i-1];
状态转移方程如下:
S[i][j]=
strsub(0,i); (if j==0)
max(S[i-1][j-1],S[i-1][j]+str[i-1]); (if 0<j<i;0<j<=k)
时间复杂度:O(n*k)
空间复杂度:O(n*k)
优化:
从上述的转移方程S[i][j]=max(S[i-1][j-1],S[i-1][j]+str[i-1]),可以看出在每一次i循环中,只与i-1相关,因此不需要用单独使用一个维度的数组来存储,只需要每次通过一个变量last保存上一次的结果。因此转移方程可以简化为S[j]=max(last,S[j]+str[i-1])
时间复杂度:O(n*k)
空间复杂度:O(k)
// 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_1(str,k)<< endl;cout <<deleteKBits_2(str,k)<< endl;cout <<deleteKBits_3(str,k)<< endl;cout <<deleteKBits_4(str,k)<< endl;return 0;
}
(笔试题)删除K位数字相关推荐
- 字符串形式的整数,删除k位,使得到的数字最小
参加一公司的面试,其中一题如下: 字符串形式的整数,删除k位,使得到的数字最小.如"10239",删除1位,得到最小数239:"14329",删除3位,最小数为 ...
- LeetCode移掉k位数字(贪心算法)python
描述 给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小. num的长度小于10002,且将≥k.给定的num不包含任何前导零. 您在真实的面试中是否遇到过这个题? ...
- leetcode402. 移掉K位数字
给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小. 注意: num 的长度小于 10002 且 ≥ k. num 不会包含任何前导零. 示例 1 : 输入: nu ...
- LeetCode 402. 移掉K位数字(贪心,单调栈)
1. 题目 给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小. 注意: num 的长度小于 10002 且 ≥ k. num 不会包含任何前导零. 示例 1 : ...
- 贪心---移掉K位数字
题目 给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小. 注意: num 的长度小于 10002 且 ≥ k. num 不会包含任何前导零. 示例 1 : 输入: ...
- LeetCode-402:移除k位数字
题目描述: 给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小. 注意: num 的长度小于 10002 且 ≥ k. num 不会包含任何前导零. 示例 1 : ...
- LeetCode 402. 移掉K位数字 中等难度
402. 移掉K位数字 题目: 给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小. 注意: num 的长度小于 10002 且 ≥ k. num 不会包含任何前导 ...
- 402.移掉K位数字,使得剩下数字最小
思路 这道题让我们从一个字符串数字中删除 k 个数字,使得剩下的数最小.也就说,我们要保持原来的数字的相对位置不变. 以题目中的 num = 1432219, k = 3 为例,我们需要返回一个长度为 ...
- 402. 移掉K位数字(单调栈)
给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小. 注意: num 的长度小于 10002 且 ≥ k. num 不会包含任何前导零. 示例 1 : 输入: nu ...
最新文章
- 霍尔传感器测量转向的方法
- esp8266环境搭建
- vue中refs的使用
- 【转载保存】推荐ApacheCN开源的一个机器学习路线图
- notepad++ 偶数行_C ++程序查找前N个偶数的立方和
- redis学习-redis事务
- Linux 环境下安装 MySQL,各种踩坑、疑难杂症 | 原力计划
- android 如何开发出一款知名应用:构思篇
- PTA 7-2 深入虎穴 (30 分)
- UVA 11859 Division Game[Nim游戏]
- 电脑键盘下划线怎么打_苹果电脑键盘失灵怎么办,维护方法!
- 【解决方案】施工现场如何实现全方位视频监控?EasyGBS视频智能告警分析平台搭建智慧工地
- mysql handler socket_mysql-handlersocket
- linux下用C/C++和socket实现的驾校约车助手
- sqlmap绕过waf的脚本介绍(tamper脚本介绍)
- 亲属关系--并查集训练T1
- Kill Demodogs——c++——pow_na的博客
- IT就业前景怎么样?好不好?
- Go语言教程(二)Go语言基础编程
- 极简 ssh之 scp