leetcode笔记总结——(9)去除重复字母 一类题目总结(python和C++描述)

这里类题目大概是这样的:
给你一个字符串,让你去除一些字符,然后使得剩余的字符串的字典序最小(字典序最小,其实可以理解成ASCII值最小,比如ab就比ba小,因为从左到右比每一个字符,a的ASCII比b的小)。

1、第一题:移掉K位数字

1.1 题目描述:

在这里插入图片描述

1.2 实现思路:

题目要求我们删除k个数字,让剩余的 数字 组合成的 数 的值最小,并且这些数字的前后顺序是不能改变的。

同时,我们知道:对于两个数 123a456 和 123b456,如果 a > b, 那么数字 123a456 大于 数字 123b456,否则数字 123a456 小于等于数字 123b456。也就说,两个相同位数的数字大小关系取决于第一个不同的数的大小。

因此,我们就可以先从最左边判断,如果前面一个数字比后面的数字大,那么我们就可以去除前面的数字。
去除一个,则让k减一,直到k=0停止去除。因此实现的思路是:

(1)从左到右开始遍历;
(2)对于遍历到的元素,我们选择保留,但是我们可以选择性丢弃前面相邻的元素,丢弃与否的依据如上面所阐述的方法(如果前面一个数字比后面的数字大,那么我们就可以去除前面的数字),直到前面的元素比当前元素小才停止丢弃。
(3)进入下一次遍历。

看一个例子:

以题目中的 num = 1432219, k = 3 为例的图解过程如下:

在这里插入图片描述

由于 1 没有左侧相邻元素,因此没办法丢弃。

在这里插入图片描述

由于 4 比左侧相邻的 1 大。如果选择丢弃左侧的 1,那么会使得剩下的数字更大(开头的数从 1 变成了 4)。因此我们仍然选择不丢弃。

在这里插入图片描述

由于 3 比左侧相邻的 4 小。 如果选择丢弃左侧的 4,那么会使得剩下的数字更小(开头的数从 4 变成了 3)。因此我们选择丢弃。

后面的做法,思路和前面相同,就再不分析了。

还需要注意:我们每次丢弃一个元素时,就让我们的k减一。如果我们遍历完了,我们的k还不为0呢?这个时候,我们就可以再把最后面的k个值丢弃,然后剩余的元素,就是我们的答案了。

按照上面的思路,我们来选择数据结构。由于我们需要保留和丢弃相邻的元素,因此使用栈这种在一端进行添加和删除的数据结构是再合适不过了,我们来看下代码实现。

其实看完上面的思路,我们用的思想是贪心算法

1.3 代码实现:

(1)python代码:

细节都在代码的注释里。

class Solution:
    def removeKdigits(self, num, k):
        stack = [] # 定义栈
        remain = len(num) - k # 计算去除k个值后,还剩余元素的个数

        for digit in num: # 开始遍历每一个元素
            while k and stack and stack[-1] > digit: # k>0并且当前元素<栈顶(前一个)元素,则出栈
                stack.pop()
                k -= 1
            stack.append(digit)
        return ''.join(stack[:remain]).lstrip('0') or '0' # 去除前导0,并且转成字符串

(2)C++代码:

class Solution {
   
public:
    string removeKdigits(string num
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值