"小红删数字"是牛客网算法题库中的一道经典题目,主要考察对数字处理和贪心算法的理解。题目描述为:给定一个由数字组成的字符串s和一个整数k,要求从字符串中删除k个数字,使得剩下的数字组成的数最小。
这道题之所以被选为每日一题,是因为它完美结合了字符串操作和贪心算法的应用场景。在实际编程面试中,类似的问题经常出现在大厂的笔试环节,比如字节跳动、腾讯等公司的算法题中都有变种题目。
最直观的解法是尝试所有可能的删除组合,然后比较得到最小值。对于一个长度为n的字符串,要删除k个数字,组合数为C(n,k),当n较大时,这种解法的时间复杂度会呈指数级增长,显然不可行。
更优的解法是采用贪心算法,其核心思想是:在每一步删除操作中,都做出当前看起来最优的选择,即删除能使剩余数字最小的那个数字。具体来说:
这种解法的时间复杂度为O(n),因为每个数字最多被处理(比较和可能的删除)一次。
python复制def removeKDigits(num: str, k: int) -> str:
stack = []
for digit in num:
while k > 0 and stack and stack[-1] > digit:
stack.pop()
k -= 1
stack.append(digit)
# 如果还有剩余需要删除的数字,从末尾删除
if k > 0:
stack = stack[:-k]
# 去除前导零
return ''.join(stack).lstrip('0') or '0'
贪心算法的正确性可以通过以下两点来理解:
对于数字字符串,要使最终结果最小,应该尽可能让小的数字出现在高位。因此当遇到一个数字比它后面的数字大时,删除它可以让更小的数字前移。
这种局部最优的选择能够保证全局最优,因为每次删除都使得当前剩余字符串在相同删除次数下尽可能小。
在拼接最终结果时,需要注意去除前导零。例如输入"10200"和k=1,正确结果应该是"200"而不是"0200"。
当输入全为"0"时,无论删除多少个数字,结果都应该是"0"而不是空字符串。
当k等于字符串长度时,直接返回"0"。
这类数字删除问题在实际中有多种应用:
可以使用双指针法直接在原字符串上进行修改,将空间复杂度优化到O(1),但会牺牲代码的可读性。
对于牛客网的算法题库,建议:
这道"小红删数字"题目很好地训练了贪心算法的应用能力,建议掌握后可以尝试LeetCode上的相似题目,如"402. Remove K Digits"等,加深理解。