删除K个数字后的最小值(贪心算法实现)

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

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

思路:

把原整数的所有数字从左到右进行比较,如果发现某一位数字大于它右面的数字,那么在删除该数字之后,必然会使该数位的值降低。这种求局部最优解,最终得到全局最优解的思想,叫作“贪心算法”。

如果要删除k个数字,那么将遍历数字作为外层循环,以k作为外层循环,再结合栈的使用。将遍历的数字逐个入栈,遇到入栈进来的数字小于栈顶的数字时,将栈顶的数字出栈,再将该遍历的数字入栈,否则就直接将数字压栈。当出栈的数字达到k个时,将剩下的数字全部入栈即可。

举例:"541270936",去除3个数字。

  1. 5入栈,stack=[5]
  2. 4入栈,判断4<5,5出栈,4入栈。stack=[4]。出栈一次,num=1
  3. 1入栈,判断1<4,4出栈,1入栈。stack=[1]。出栈一次,num=2
  4. 2入栈,判断2>1,2直接入栈。stack=[1,2]
  5. 7入栈,判断7>2,7直接入栈。stack=[1,2,7]
  6. 0入栈,判断0<7,7出栈,0入栈。stack=[1,2,0]。出栈一次,num=3。此时出栈了3次,相当于去除了3个数字。满足要求。那么剩下的字符就直接入栈就可以了。
  7. 剩余字符全部入栈。stack=[1,2,0,9,3,6]

代码实现:

 1 package blogSrc;
 2
 3 import com.sun.deploy.util.StringUtils;
 4
 5 import java.util.Arrays;
 6 import java.util.Stack;
 7
 8 /**
 9  * 删除K个数字后的最小值
10  *
11  * 给出一个整数,从该整数中去掉k个数字,要求剩下的数字形成的新整数尽可能小。应该如何选取被去掉的数字?
12  * 其中,整数的长度大于或等于k,给出的整数的大小可以超过long类型的数字范围。
13  *
14  * 思路:把原整数的所有数字从左到右进行比较,如果发现某一位数字大于它右面的数字,那么在删除该数字之后,必然会使该数位的值降低。
15  * 如果要删除k个数字,那么将遍历数字作为外层循环,以k作为外层循环,再结合栈的使用。将遍历的数字逐个入栈,否则就直接将数字压栈。
16  * 遇到入栈进来的数字小于栈顶的数字时,将栈顶的数字出栈,再将该遍历的数字入栈,当出栈的数字达到k个时,
17  * 将剩下的数字全部入栈即可。
18  */
19 public class GetMinAfterRemoveKDigits {
20
21     public static void main(String[] args){
22         String originStr = "541270936";
23         String newStr = new GetMinAfterRemoveKDigits().getMinAfterRemoveKDigits(originStr,3);
24         System.out.println("OldString is: " + originStr);
25         System.out.println("NewString is: " + newStr);
26     }
27
28     public String getMinAfterRemoveKDigits(String originStr, int k){
29         char[] originArr = originStr.toCharArray();
30         Stack<Character> stack = new Stack<>();
31         stack.push(originArr[0]);
32         int num = 0;
33         for (int i=0; i<originArr.length; i++){
34             if (num == k){
35                 stack.push(originArr[i]);
36             }else {
37                 if (originArr[i] <= stack.peek()) {
38                     stack.pop();
39                     stack.push(originArr[i]);
40                     num++;
41                 }else {
42                     stack.push(originArr[i]);
43                 }
44             }
45
46         }
47
48         StringBuffer result = new StringBuffer();
49         for (int i=0; i<stack.size(); i++){
50             result.append(stack.get(i));
51         }
52         return result.toString();
53     }
54 }

结果:

OldString is: 541270936
NewString is: 1270936

原文地址:https://www.cnblogs.com/zldmy/p/11517369.html

时间: 2024-08-28 14:20:13

删除K个数字后的最小值(贪心算法实现)的相关文章

(笔试题)删除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 deleteKBi

算法学习——贪心算法之删数字(求最小值)

算法描述 在给定的n位数字,删除其中的k位数字( k < n),使得最后的n-k为数字为最小值(原次序不变) 算法思路 考虑到是要移出数字,我们使用链表设计此算法较为方便,链表可以直接移出某个位置的元素 使用贪心算法,每一步都要达到最优 从最高位开始,若下一位比上一位要小,则将上一位的数字移出,结束之后再次从最高位开始 这里需要注意,会有特例 当输入从小到大的的一个数的时候,上述算法将会无法运行,比如123456,删除1个数字变为最小,我们把6删去,这样才是最小的(即从末尾删除数字) 算法实现

算法学习——贪心算法之删数字(求最大值)

算法描述 在给定的n位数字,删除其中的k位数字( k < n),使得最后的n-k为数字为最大值(原次序不变) 算法思路 考虑到是要移出数字,我们使用链表设计此算法较为方便,链表可以直接移出某个位置的元素 使用贪心算法,每一步都要达到最优 从最高位开始,若是下一位比上一位大,则比上一位的数字移出,结束之后再次从最高位开始 例如 16489657 删除4个数字 首先比较1和6 删除1 得到 6489657 之后,再次比较 6和4 往后推 可得到 689657 以此类推 删除4个数字之后 可得到 96

算法导论——lec 13 贪心算法与图上算法

之前我们介绍了用动态规划的方法来解决一些最优化的问题.但对于有些最优化问题来说,用动态规划就是"高射炮打蚊子",采用一些更加简单有效的方法就可以解决.贪心算法就是其中之一.贪心算法是使所做的选择看起来是当前最佳的,期望通过所做的局部最优选择来产生一个全局最优解. 一. 活动选择问题 [问题]对几个互相竞争的活动进行调度:活动集合S = {a1, a2, ..., an},它们都要求以独占的方式使用某一公共资源(如教室),每个活动ai有一个开始时间si和结束时间fi ,且0 ≤ si &

贪心算法解硬币找零问题

假如有一种货币,它有面值为1分.2分.5分和1角的硬币,最少需要多少个硬币来找出K分钱的零钱? 按照贪心算法的思想,需要不断地使用面值最大的硬币.如果要找零的值小于最大的硬币值,则尝试第二大的硬币,依次类推. 代码如下: #include <iostream> using namespace std; #define ONE 1 #define TWO 2 #define FIVE 5 #define TEN 10 int main() { int money; int one=0,two=0

算法导论----贪心算法,删除k个数,使剩下的数字最小

先贴问题: 1个n位正整数a,删去其中的k位,得到一个新的正整数b,设计一个贪心算法,对给定的a和k得到最小的b: 一.我的想法:先看例子:a=5476579228:去掉4位,则位数n=10,k=4,要求的最小数字b是n-k=6位的: 1.先找最高位的数,因为是6位数字,所以最高位不可能在后5位上取到(因为数字的相对顺序是不能改变的,假设如果取了后五位中倒数第5位的7,则所求的b就不可能是6位的了,最多也就是4位的79228)理解这点很重要!所以问题变成从第1位到第k+1(n-(n-k-1))取

2017.12.27 算法分析 贪心算法删除数字求最小值问题

1个n位正整数a,删去其中的k位,得到一个新的正整数b,设计一个贪心算法,对给定的a和k得到最小的b: 一.我的想法:先看例子:a=5476579228:去掉4位,则位数n=10,k=4,要求的最小数字b是n-k=6位的: 1.先找最高位的数,因为是6位数字,所以最高位不可能在后5位上取到(因为数字的相对顺序是不能改变的,假设如果取了后五位中倒数第5位的7,则所求的b就不可能是6位的了,最多也就是4位的79228)理解这点很重要!所以问题变成从第1位到第k+1(n-(n-k-1))取最小值,为什

贪心算法-移除K个数字

1.题目描述 给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小. 注意: num 的长度小于 10002 且 ≥ k. num 不会包含任何前导零. 2.题目分析: 题目简介明了,就是把给定的数字删除指定个数的数字使删除之后的数字是同等位数数字中最小的那个.但是需要注意的是,题目中给的数字是字符串的形式并且输出结果也是字符串的形式,这就涉及到字符串和数字之间的相互转化问题. 题目中要求删除的数字个数是不确定的,那么我们可以根据数学知识先分析当我们删除一个数字

【LeetCode】402、移除K位数字

1.移除K位数字 题目:402. 移掉K位数字 题目描述: ??给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小.(num 的长度小于 10002 且 ≥ k. num 不会包含任何前导零.) 示例 : 输入: num = "1432219", k = 3 输出: "1219" 解释: 移除掉三个数字 4, 3, 和 2 形成一个新的最小的数字 1219. 输入: num = "10200", k = 1 输