LeetcodeMedium-【402. 移掉K位数字】

给定一个以字符串表示的非负整数 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。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/remove-k-digits
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路:https://leetcode-cn.com/problems/remove-k-digits/solution/yi-diao-kwei-shu-zi-by-leetcode/

上述的规则使得我们通过一个接一个的删除数字,逐步的接近最优解。

这个问题可以用贪心算法来解决。上述规则阐明了我们如何接近最终答案的基本逻辑。一旦我们从序列中删除一个数字,剩下的数字就形成了一个新的问题,我们可以继续使用这个规则。

我们会注意到,在某些情况下,规则对任意数字都不适用,即单调递增序列。在这种情况下,我们只需要删除末尾的数字来获得最小数。

我们可以利用栈来实现上述算法,存储当前迭代数字之前的数字。

对于每个数字,如果该数字小于栈顶部,即该数字的左邻居,则弹出堆栈,即删除左邻居。否则,我们把数字推到栈上。
我们重复上述步骤(1),直到任何条件不再适用,例如堆栈为空(不再保留数字)。或者我们已经删除了 k 位数字。


我们在上图中演示了该算法的工作原理。给定输入序列 [1,2,3,4,5,2,6,4] 和 k=4,规则在 5 触发。删除数字 5 后,规则将在数字 4 处再次触发,直到数字 3。然后,在数字 6 处,规则也被触发。

在上述主循环之外,我们需要处理一些情况,以使解决方案更加完整:

当我们离开主循环时,我们删除了 m 个数字,这比要求的要少,即(m<k)。在极端情况下,我们不会删除循环中单调递增序列的任何数字,即 m==0。在这种情况下,我们只需要从序列尾部删除额外的 k-m 个数字。
一旦我们从序列中删除 k 位数字,可能还有一些前导零。要格式化最后的数字,我们需要去掉前导零。
我们最终可能会从序列中删除所有的数字。在这种情况下,我们应该返回零,而不是空字符串。

 

class Solution:
    def removeKdigits(self, num: str, k: int) -> str:
        stack = []
        for i in range(len(num)):
            if stack == []:
                stack.append(num[i])
                continue
            elif int(num[i]) < int(stack[-1]) and k > 0:
                # 一直往前弹出
                while stack != [] and int(num[i]) < int(stack[-1]) and k > 0:
                    stack.pop()
                    k -= 1
            stack.append(num[i])
        # print(stack)
        while k > 0: 
            stack.pop()
            k -= 1
        if stack == []:
            return "0"
        return str(int(''.join(stack)))
        
class Solution:
    def removeKdigits(self, num: str, k: int) -> str:
        numStack = []
        
        # Construct a monotone increasing sequence of digits
        for digit in num:
            while k and numStack and numStack[-1] > digit:
                numStack.pop()
                k -= 1
        
            numStack.append(digit)
        
        # - Trunk the remaining K digits at the end
        # - in the case k==0: return the entire list
        finalStack = numStack[:-k] if k else numStack
        
        # trip the leading zeros
        return "".join(finalStack).lstrip('0') or "0"

作者:LeetCode
链接:https://leetcode-cn.com/problems/remove-k-digits/solution/yi-diao-kwei-shu-zi-by-leetcode/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
发布了314 篇原创文章 · 获赞 22 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_39451578/article/details/105081058