题目:

现有一个 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位数字相关推荐

  1. 字符串形式的整数,删除k位,使得到的数字最小

    参加一公司的面试,其中一题如下: 字符串形式的整数,删除k位,使得到的数字最小.如"10239",删除1位,得到最小数239:"14329",删除3位,最小数为 ...

  2. LeetCode移掉k位数字(贪心算法)python

    描述 给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小. num的长度小于10002,且将≥k.给定的num不包含任何前导零. 您在真实的面试中是否遇到过这个题? ...

  3. leetcode402. 移掉K位数字

    给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小. 注意: num 的长度小于 10002 且 ≥ k. num 不会包含任何前导零. 示例 1 : 输入: nu ...

  4. LeetCode 402. 移掉K位数字(贪心,单调栈)

    1. 题目 给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小. 注意: num 的长度小于 10002 且 ≥ k. num 不会包含任何前导零. 示例 1 : ...

  5. 贪心---移掉K位数字

    题目 给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小. 注意: num 的长度小于 10002 且 ≥ k. num 不会包含任何前导零. 示例 1 : 输入: ...

  6. LeetCode-402:移除k位数字

    题目描述: 给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小. 注意: num 的长度小于 10002 且 ≥ k. num 不会包含任何前导零. 示例 1 : ...

  7. LeetCode 402. 移掉K位数字 中等难度

    402. 移掉K位数字 题目: 给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小. 注意: num 的长度小于 10002 且 ≥ k. num 不会包含任何前导 ...

  8. 402.移掉K位数字,使得剩下数字最小

    思路 这道题让我们从一个字符串数字中删除 k 个数字,使得剩下的数最小.也就说,我们要保持原来的数字的相对位置不变. 以题目中的 num = 1432219, k = 3 为例,我们需要返回一个长度为 ...

  9. 402. 移掉K位数字(单调栈)

    给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小. 注意: num 的长度小于 10002 且 ≥ k. num 不会包含任何前导零. 示例 1 : 输入: nu ...

最新文章

  1. 霍尔传感器测量转向的方法
  2. esp8266环境搭建
  3. vue中refs的使用
  4. 【转载保存】推荐ApacheCN开源的一个机器学习路线图
  5. notepad++ 偶数行_C ++程序查找前N个偶数的立方和
  6. redis学习-redis事务
  7. Linux 环境下安装 MySQL,各种踩坑、疑难杂症 | 原力计划
  8. android 如何开发出一款知名应用:构思篇
  9. PTA 7-2 深入虎穴 (30 分)
  10. UVA 11859 Division Game[Nim游戏]
  11. 电脑键盘下划线怎么打_苹果电脑键盘失灵怎么办,维护方法!
  12. 【解决方案】施工现场如何实现全方位视频监控?EasyGBS视频智能告警分析平台搭建智慧工地
  13. mysql handler socket_mysql-handlersocket
  14. linux下用C/C++和socket实现的驾校约车助手
  15. sqlmap绕过waf的脚本介绍(tamper脚本介绍)
  16. 亲属关系--并查集训练T1
  17. Kill Demodogs——c++——pow_na的博客
  18. IT就业前景怎么样?好不好?
  19. Go语言教程(二)Go语言基础编程
  20. 极简 ssh之 scp

热门文章

  1. 程序员如何才能提高自己?通过一次重构代码讲解自己的感受【有代码比较】...
  2. RED HAT LINUX 9.0的安装文本模式(2)
  3. python的数据类型和变量
  4. 【深度学习之美】卷地风来忽吹散,积得飘零美如画(入门系列之十)
  5. mysql 协议的ResultsetRow包及解析
  6. Apche Httpd安装与配置
  7. Present ViewController详解
  8. cdoj 题目简单分类
  9. css选择器顺序的小技巧
  10. 运维的shell小编(6)