贪心算法-移除K个数字

1、题目描述

  给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小。

注意:

  • num 的长度小于 10002 且 ≥ k。
  • num 不会包含任何前导零。

2、题目分析:

  题目简介明了,就是把给定的数字删除指定个数的数字使删除之后的数字是同等位数数字中最小的那个。但是需要注意的是,题目中给的数字是字符串的形式并且输出结果也是字符串的形式,这就涉及到字符串和数字之间的相互转化问题。

  题目中要求删除的数字个数是不确定的,那么我们可以根据数学知识先分析当我们删除一个数字的时候应该怎样删除才能保证删除之后的数字是最小的呢?依据下边的数字1432219为例,当我们要删除一个数字的时候,我们需要在左边(高位)尽可能的删除较大的数字。最后发现删除4之后是最小的数字,其实仔细分析就会发现:删除这一个数字就是从左边的高位1开始比较,当发现后一个数字比前一个数字小的时候我们就需要把前一个数字删除掉,这样就能保证满足要求。

输入: num = "1432219", k = 3
输出: "1219"
解释: 移除掉三个数字 4, 3, 和 2 形成一个新的最小的数字 1219。

3、算法思想:

  1、首先把当前给定的字符串表示的数字从高位开始逐个分离出来

  2、设置一个栈,用于存放字符串分离出来的数字,从高到底逐个压入栈中。但是这里涉及到两个问题:栈是否为空、压入栈的数字是否是0

  3、每分离出来一个数字,就进行一些判断:当前待入栈的数字和栈顶元素比较,如果栈顶元素大且K的值要大于0(保证移除指定个数的数字)且栈不为空就要先执行出栈操作然后再把这个待入栈元素入栈。

  4、如果不满足3的情况,依然要考虑站是否为空的情况和待入栈的元素值是否为0的情况,因为当栈为空且待入栈的元素值为0的时候也不能入栈。除了这种情况之后其他情况都是可以入栈的。

  5、如果是一个12345这样情况的数字,我们发现执行完3和4的情况之后K的值依然是大于0的。那么当上边的过程执行完毕我们还要单独判断K的值是否大于0,如果大于0的话,就要从栈顶删除若干个元素是k的值为0.

  6、最后取出栈中元素组成字符串输出结果。

4、解题代码:

 1 package com.baozi.test;
 2
 3 import java.util.Stack;
 4 import java.util.Vector;
 5
 6 /**
 7  * @author BaoZi
 8  * @create 2019-05-14-17:03
 9  */
10 public class Solution4 {
11     public static void main(String[] args){
12 //        String num="1432219";
13         String num1="100200";
14 //        String result = Solution4.removeKdigits1(num, 3);
15         String result1 = Solution4.removeKdigits(num1, 1);
16 //        System.out.println(result);
17         System.out.println(result1);
18     }
19     public static String removeKdigits1(String num, int k){
20         //设置变量result用于保存最后的结果
21         String result="";
22         //设置一个栈数据结构
23         Vector<Integer> vector = new Vector<>();
24         //通过for循环把满足当前条件的数字都压入栈中
25         for (int i = 0; i <num.length() ; i++) {
26             int temp=num.charAt(i)-‘0‘;
27             //待入栈元素值如果比栈顶元素值小的话,栈顶元素先执行出栈操作
28             while(vector.size()!=0&&vector.elementAt(vector.size()-1)>temp&&k>0){
29                 vector.remove(vector.size()-1);
30                 k--;
31             }
32             if(vector.size()!=0||temp!=0){
33                 vector.add(temp);
34             }
35         }
36         //还要判断当for循环执行完毕之后K的值是否为0的情况
37         while(k>0&&vector.size()!=0){
38                 vector.remove(vector.size()-1);
39                 k--;
40         }
41         //接下来就是把栈中的元素全部取出来组成字符串
42         while(vector.size()!=0){
43             result=vector.remove(vector.size()-1)+result;
44         }
45         return result;
46     }
47 public static String removeKdigits(String num, int k){
48     //设置变量result用于保存最后的结果
49     String result="";
50     //设置一个栈数据结构
51     Stack<Integer> stack = new Stack<>();
52     //通过for循环把满足当前条件的数字都压入栈中
53     for (int i = 0; i <num.length() ; i++) {
54         int temp=num.charAt(i)-‘0‘;
55         //待入栈元素值如果比栈顶元素值小的话,栈顶元素先执行出栈操作
56         while(stack.size()!=0&&stack.peek()>temp&&k>0){
57             stack.pop();
58             k--;
59         }
60         if(stack.size()!=0||temp!=0){
61             stack.push(temp);
62         }
63     }
64     //还要判断当for循环执行完毕之后K的值是否为0的情况
65     while(k>0&&stack.size()!=0){
66         stack.pop();
67         k--;
68     }
69     //接下来就是把栈中的元素全部取出来组成字符串
70     while(stack.size()!=0){
71         result=stack.pop()+result;
72     }
73     return result;
74 }
75 }

原文地址:https://www.cnblogs.com/BaoZiY/p/10861404.html

时间: 2024-09-30 11:11:36

贪心算法-移除K个数字的相关文章

【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 输

算法46----移除K位数字

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

算法导论----贪心算法,删除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))取

Leetcode 402. 移掉K位数字

// 贪心算法,当前遇到的数,比栈顶的元素小,就将栈顶元素给弹出,直至遇到比栈顶大或者是栈为空才停止,字符串保证是一个正常的数字序列.class Solution { public: string removeKdigits(string num, int k) { std::vector<int> S;//为了遍历,因此可以用vector来进行模拟. std::string result = "";// 保存最后的结果 for(int i=0; i<num.size

数据结构与算法简记--贪心算法

贪心算法 贪心算法问题解决步骤 第一步,当我们看到这类问题的时候,首先要联想到贪心算法:针对一组数据,我们定义了限制值和期望值,希望从中选出几个数据,在满足限制值的情况下,期望值最大. 第二步,我们尝试看下这个问题是否可以用贪心算法解决:每次选择当前情况下,在对限制值同等贡献量的情况下,对期望值贡献最大的数据. 第三步,我们举几个例子看下贪心算法产生的结果是否是最优的. 贪心算法实战分析 分糖果:有 m 个糖果和 n 个孩子.要把糖果分给这些孩子吃,但是糖果少,孩子多(m<n),所以糖果只能分配

算法导论--贪心算法与动态规划(活动选择问题)

活动选择问题 有一个教室,而当天有多个活动,活动时间表如下:找出最大兼容活动集!活动已按结束时间升序排序. 动态规划 采用动态规划需要满足两个条件:1.最优子结构2.子问题重叠 令Sij表示在ai结束后和aj开始前活动的集合,假定Aij为活动集合Sij的最大兼容子集,其中包含活动ak.问题变成求Sik与Skj最大兼容活动子集Aik与Akjz.我们用c[i,j]表示Sij的最优解的大小. 则c[i,j] = c[i,k]+c[k,j]+1;最后我们需要遍历所有可能的k值,找出最大的一个划分作为c[

数据结构与算法-贪心算法

#include "pch.h" #include <iostream> #include <stdio.h> int main() { const int RMB[] = { 200, 100, 20, 5, 1 }; const int NUM = 5; int X = 628; int count = 0; for (int i = 0; i < NUM; i++) { int use = X / RMB[i]; count += use; X =

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

给出一个整数,从该整数中去掉k个数字,要求剩下的数字形成的新整数尽可能小.应该如何选取被去掉的数字? 其中,整数的长度大于或等于k,给出的整数的大小可以超过long类型的数字范围. 思路: 把原整数的所有数字从左到右进行比较,如果发现某一位数字大于它右面的数字,那么在删除该数字之后,必然会使该数位的值降低.这种求局部最优解,最终得到全局最优解的思想,叫作“贪心算法”. 如果要删除k个数字,那么将遍历数字作为外层循环,以k作为外层循环,再结合栈的使用.将遍历的数字逐个入栈,遇到入栈进来的数字小于栈

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))取最小值,为什