leetcode 402. Remove K Digits

题目

给定一个用字符串表示的非负整数num,从这个整数中去掉k个数字,使得到的数字最小。

思路

  1. 暴扫,组合出剩余位数的全都可能的数字,逐个插入堆中,最后取出堆顶元素,TLE
  2. 思考发现从左到右逐个扫描数字,如果后一个数字小于等于前一个数字,就把前一个数字去掉,得到的就是去掉一个数字以后的最小数字,依此类推,直到扫到最后一个数字,这时整个数字是按位数字从小到大排列的,如果此时去掉的数字不足k个,就从最后一位逐个向左去除,也就是此时的数字保留len(num)-k位,这种方法既可以用堆栈也可以用指针实现。用指针的话pop列表比较慢,将pop操作改成重新拼接两个字符串更快一点,但是空间耗费比较大,用堆栈的话时空复杂度都更低。

代码

# brute
import heapq
from itertools import combinations
len_num = len(num)
if len_num == k:
    return 0
a = combinations(num, len_num - k)
h = []
while True:
    try:
        heapq.heappush(h, int(''.join(next(a))))
    except StopIteration:
        break
return str(h[0])
# stack
len_num = len(num)
if len_num < 2 or len_num == k:
    return '0'
stack = []
counter = 0
for i in num:
    if not stack:
        stack.append(i)
        continue

    while stack and i < stack[-1] and counter < k:
        stack.pop()
        counter += 1
        if counter == k:
            break
    stack.append(i)
return str(int(''.join(stack)))[:len_num-k]
# pointer
len_num = len(num)
if len_num < 2 or len_num == k:
    return '0'
i = 0
counter = 0
while counter < k:
    if int(num[i]) <= int(num[i + 1]):
        if i == len(num) - 2:
            break
        else:
            i = i + 1
    else:
        num = num[:i] + num[i + 1:]
        if i > 0:
            i = i - 1
        counter += 1
return str(int(num))[:len_num - k]

猜你喜欢

转载自blog.csdn.net/qq_35753140/article/details/84500548