给定一个以字符串表示的非负整数 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。
class Solution(object):
def removeKdigits(self, num, k):
"""
:type num: str
:type k: int
:rtype: str
"""
stack = [] # 存放目前觉得最好的数
for digit in num:
# 将栈顶的数字(从顶往下依次与digit比较)
# 贪心策略:作出目前最好的选择 不关心后效性 越靠前的数字越小越好
# 在约束条件k>0下 将当前数字与栈顶数字比较 如果小 说明选择当前数字是更好的 因为构成的数字更小
# 对于目前来说 把digit这个数字放到最"贪心"的位置去 为其贪心选择
# 具有最优子结构的特点:譬如1432 会选择12 而把43删去(k是前提) 12为最优解1219的子结构
# 而栈顶的数字出栈意味着删除了栈顶数字 k需要减去1
while k > 0 and stack and stack[-1] > digit:
stack.pop()
k -= 1
stack.append(digit)
# 特殊情况 数组递增 则循环会存入所有的数字 因此需要删除最后的k个数字
# 否则k肯定为0 即删除了k个数 退出循环
m = len(stack)
stack = stack[:m-k]
# 删除前导0 返回字符串 如果为空 返回"0"
return "".join(stack).lstrip('0') or "0"