Leetcode 402. 移掉K位数字(贪心+栈)----python

前言:
这题真的有点难的,改了几遍之后把自己给绕晕了。。。然后花了点时间把思路捋清楚了。要考虑比较多种情况。

1. 题目描述

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

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

示例 2 :
输入: num = “10200”, k = 1
输出: “200”
解释: 移掉首位的 1 剩下的数字为 200. 注意输出不能有任何前导零。

示例 3 :
输入: num = “10”, k = 2
输出: “0”
解释: 从原数字移除所有的数字,剩余为空就是0。

2. 解题思路

贪心算法 + 栈
步骤

  • 每一步元素都入栈,比较栈顶元素和待入栈元素的大小,栈顶元素更大,则pop,然后将
    待入栈元素入栈。否则,将待入栈元素入栈。当pop元素个数=k时,return经过贪心算法的已经入栈的元素+num中未处理的元素。
  • 对于有可能是‘123456’升序这种情况,元素会全部入栈,这种情况下只需取前len(num)-k个元素数。
  • 可能有前导0的出现,先转化为int,再转为str,就能解决。

先分析一个实例,得出思路:
在这里插入图片描述
在这里插入图片描述
如果要从最高位遍历K次,时间复杂度太高,所以,想到用栈去进行优化!!
在这里插入图片描述

3. 代码实现

class Solution(object):
    def removeKdigits(self, num, k):
        if len(num) <= k:
            return '0'
        if k == 0:
            return num
        stack,count=[],0
        #对于字符串里的每一个元素
        for i,x in enumerate(num):
            #如果栈顶元素比待入栈元素要大,则删除栈顶元素,同时将待入栈元素push, count加1
            while len(stack)>0 and x < stack[-1]:
                stack.pop()
                count+=1
                #若入栈的元素已经为k
                if count == k:
                    #一般情况下,经过贪心算法的已经入栈的元素+num中未处理的元素
                    #当有前导0时,由于先转为int,前导0消失,然后转为str类型,这就解决了前导0的问题
                    return str(int(''.join(stack)+num[i:]))
            stack.append(x)
        #特殊情况下一直是升序,如123456,则只返回前len(num)-k个数
        return str(int(''.join(stack[:len(num)-k])))

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/u013075024/article/details/93197107