删去k个数字后的最小值

news/2025/1/6 21:02:14/文章来源:https://www.cnblogs.com/changming06/p/18652794

8.删去k个数字后的最小值

题目

给出一个整数,从该整数中去掉k个数字,要求剩下的数字形成的新整数经可能小。应该如何选取被去掉的数字?

其中整数的长度大于或等于k,给出的整数的大小可以超过long类型的数字范围。

举例:整数1593210,删除3个数字,新整数最小为1210;整数5674201,删除3个数字,新整数最小值为4210。

思路

上例:整数1593210,要求删除1个数字,找出最小的整数。

此时,无论删除那个数字,结果都是从7位整数,变为6位整数。既然都是6位整数,显然优先将高位的数字降低,这样对新整数的值影响最大。

但是不代表,优先删除最高位的整数,例如1593210,如果移除最高位1,结果是593210,这不是最小值,因为有193210就比593210小。

这删除一位的分析,最小值,能直接看出来,移除9是最小的,153210。但是计算机,是不能看的,所以要找出,删除一位时的规律,才能写程序。

还是1593210,删除9得到最小值的规律。很简单,把原整数的所有数字从左到右进行比较, 如果发现某一位数字大于它右面的数字,那么在删除该数字后,必然会使该数位的值降低,因为右面比它小的数字顶替了它的位置。

1593210,删除3位的最小值。按照规律,移除9 -> 153210,移除5 -> 13210,移除3 -> 1210,1210为最小值。

这样依次求得局部最优解,最终得到全局最优解的思想,叫作贪心算法。10549

代码

第一版
    /*** 删除整数的k个整数,获取函数后的最小值** @param num 原整数* @param k   删除数量* @return 最小值*/public static String removeKDigits(String num, int k) {String newNum = num;for (int i = 0; i < k; i++) {boolean hasCut = false;//每次移除一位,保证当前步,移除1位的最小值for (int j = 0; j < newNum.length() - 1; j++) {//char类型 在java里可以直接比较if (newNum.charAt(j) > newNum.charAt(j + 1)) {newNum = newNum.substring(0, j) + newNum.substring(j + 1);//substring(i),等于substring(i,str.length())hasCut = true;break;}}//从左往右遍历,未找到左位大于右位的数字,移除最后一位if (!hasCut)newNum = newNum.substring(0, newNum.length() - 1);//substring(i,j)截取范围是[i,j),i,j代表的是索引newNum = removeZero(newNum);//移除整数左侧的数字0}if (newNum.length() == 0)return "0";//所有数字都被删除,返回字符串0return newNum;}private static String removeZero(String num) {for (int i = 0; i < num.length()-1; i++) {if (num.charAt(0) != '0')break;num = num.substring(1);}return num;}public static void main(String[] args) {System.out.println(removeKDigits("1593210", 3));//1210System.out.println(removeKDigits("301200", 1));//1200System.out.println(removeKDigits("20", 2));//0System.out.println(removeKDigits("5674201", 3));//4201}
第二版

上述代码,使用了2层循环,外层循环次数,就是删除的数字个数k,内存从左到右遍历所有数字。符合条件(当前位大于后一位)的数字,利用substring()函数,截取字符串,构成新字符串。代码复杂度O(kn)。

代码的功能实现正常,但是性能不好。

  • 每次都从左往右遍历,但是因为每次删除是删除的首个满足条件的数字,所以下次,只要从上一次删除的位置开始往右遍历即可。
  • substring()底层实现,涉及到新字符串的创建,以及字符的逐个赋值。这个方法的时间复杂度是O(n)。因此应该,避免每删除一个数字,就调用substring方法。
    /*** 删除整数的k个整数,获取函数后的最小值** @param num 原整数* @param k   删除数量* @return 最小值*/public static String removeKDigits(String num, int k) {int newLen = num.length() - k;//使用原字符串的长度,可能会有冗余,但是是为了满足对于k==num.length()的情况,finalChar也能保存字符char[] finalChar = new char[num.length()];//默认值是'0'int top = 0;for (int i = 0; i < num.length(); i++) {char c = num.charAt(i);//当前位数字字符//finalChar[top - 1]代表的是上一位,c是当前位while (top > 0 && finalChar[top - 1] > c && k > 0) {top--;//保证在finalChar字符数组,当前位字符,替换左边一位k--;//删除次数迭代}//top>0保证,首位一定会进入到finalChar字符数组finalChar[top++] = c;//先进行finalChar[top] = c赋值操作,再进行top=top+1操作}int offset = 0;//偏移量while(offset < newLen && finalChar[offset] == '0')//获取最后字符数组中,首个不等于0字符的数字的索引,即是移除最后数字的左边的0offset++;return offset == newLen ? "0": new String(finalChar,offset,newLen - offset);//使用new String(finalChar,offset,newLen - offset),是为了去掉,左侧的'0',和创建字符数组时的默认值'0'}public static void main(String[] args) {System.out.println(removeKDigits("1593210", 3));//1210System.out.println(removeKDigits("301200", 1));//1200System.out.println(removeKDigits("20", 2));//0System.out.println(removeKDigits("5674201", 3));//4201}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/864105.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

20241322 《计算机基础与程序设计》课程总结

2024-2025-1 20241322 《计算机基础与程序设计》第十五周学习总结 作业信息 |这个作业属于哪个课程|https://edu.cnblogs.com/campus/besti/2024-2025-1-CFAP| |这个作业要求在哪里|https://www.cnblogs.com/rocedu/p/9577842.html#WEEK15| |这个作业的目标|课程总结,文中的链…

《docker基础篇:7.Docker容器数据卷》包括坑、回顾下上一讲的知识点,参数V、是什么、更干嘛、数据卷案例

《docker基础篇:7.Docker容器数据卷》包括坑、回顾下上一讲的知识点,参数V、是什么、更干嘛、数据卷案例@目录7.Docker容器数据卷7.1坑7.2 回顾下上一讲的知识点,参数V7.3 是什么7.4 能干嘛7.5 数据卷案例7.5.1 宿主vs容器之间映射添加容器卷7.5.2 读写规则映射添加说明7.5.…

DIY笔记本散热器

前言我用的笔记本是R9000P 2021H,用了快三年才发现笔记本发热量有点高,GPU 3070倒是还好不用担心过热的问题,主要是这个CPU 5800H非常积热。最近也是清完灰、涂硅脂、换完风扇了,双烤测试了下功耗能到200W但是CPU有大概70C往上的样子,考虑到这是冬季测试下的结果,这个成绩…

BJT的共射极伏安特性曲线

BJT(双极型晶体管)共射极的伏安特性曲线包括输入特性曲线和输出特性曲线,以下是详细讲解:输入特性曲线定义:描述基极电流\(i_B\)与基极-发射极电压\(v_{BE}\)之间的关系,通常以集电极-发射极电压\(v_{CE}\)为参变量,即\(i_B = f(v_{BE})|_{v_{CE}=constant}\)。 曲线形状…

检索增强生成和思维链结合: 如何创建检索增强思维链 (RAT)?

论文地址:https://arxiv.org/pdf/2403.05313 Github地址:https://github.com/CraftJarvis/RAT 想象一下,一个人工智能助手可以像莎士比亚一样写作,像专家一样推理。这听起来很了不起,对吧?但是,如果这个助手有时难以确保事实准确性,依赖过时的信息或只是编造事实,该怎…

163MusicLyrics(歌词下载工具) v6.3

一款Windows 云音乐歌词获取,支持网易云、QQ音乐。 软件特点 支持网易云、QQ音乐两家音乐提供商 支持输入歌曲 ID、输入专辑 ID、完整链接的方式进行查询 支持批量查询 && 扫盘查询 支持多种歌词原文和译文的组织方式 支持提取(部分)歌曲试听链接 支持多种保存命名规…

维度情感模型

一.维度情感模型 人类的情感是复杂繁琐的认知过程,很难对人类情感进行简单的概括,现阶段的情感模型大多分为两种,分别是离散情感模型和维度情感模型。 传统上,情感被看作是离散的类别,例如快乐、悲伤、愤怒等。离散情感模型将情感分为独立的类别,著名的心理学家Ekman等人…

Android 洛雪音乐 v1.6.0

洛雪音乐电脑版本很出名,手机版本同样是一个作者开发的产品,使用React native开发的安卓版本,软件界面清新,功能强大,该有的功能都有。同时,软件已经开源,允许所有人学习源码。获取地址:https://www.dmjf.top/2542.html

雪藏HsFreezer(游戏冻结工具) v2.09

HsFreezer 是一款让你可以随心冻结游戏的软件(游戏暂停软件、系统优化软件、进程管理软件),想玩就玩,想停就停,快捷键随心瞬发,单锁模式极致的丝滑切换,当然,不止适用游戏。更有丰富的特色系统优化功能。 PC主机,win掌机,笔记本–无脑装就对了,超大按键超大列表,触控盲操,非常巴…

Android Auto Text(自动发短信) v5.5.8 高级版

Auto Text(原Do It Later)是一款简洁好用的以后再做计划程序应用,有了 Do It Later Pro 即使您在睡觉、忙碌或不在手机旁时,也可以给某人你发送短信(SMS)。直观的提醒绝不会让您错过任何事情。它支持虚拟来电计划、SMS计划程序、电子邮件计划程序、社交网络计划程序和任务计…

洛雪音乐助手 v2.9.0 绿色版

洛雪音乐助手是一款第三方的音乐搜索下载软件,支持很多个接口。虽然软件核心没有直接解析,但是这UI的功底,绝对是国内数一数二的。值得推荐和使用! 软件支持试听,获取排行榜,是一款能当音乐软件使用的软件获取地址:https://www.dmjf.top/2268.html