刷题使我快乐,满脸开心.jpg
- 来源:力扣(LeetCode)
- 链接:https://leetcode.cn/problems/remove-k-digits/
- 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题目
给你一个以字符串表示的非负整数 num
和一个整数 k
,移除这个数中的 k
位数字,使得剩下的数字最小。请你以字符串形式返回这个最小的数字。
示例 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 。
提示:
1 <= k <= num.length <= 105
num
仅由若干位数字(0 - 9)
组成- 除了
0
本身之外,num
不含任何前导零
思路
我们很容易就能想到,最高位越小,无论后面位数数字如何,整体数值都会越小,所以,我们就从左到右遍历,找最小的最高位、第二位、等等等等。
而至于如何代码实现,那可以考虑*单调栈*
的思路:
1、从左至右每次拿一个数字,当比结果前面的数字小时则丢弃前面的数字,至多可以丢弃k
个数字,遍历完num
或者k
为0
后则退出遍历,
2、当然,也有可能遍历完之后,k
还是大于0
,那么就需要截取下结果,从num
尾部截取即可。
代码
func removeKdigits(num string, k int) string {
if k >= len(num) {
return "0"
}
numBytes := []byte(num)
var resBytes []byte
remain := len(num) - k
for _, charByte := range numBytes {
for k > 0 && len(resBytes) > 0 && resBytes[len(resBytes)-1] > charByte {
resBytes = resBytes[:len(resBytes)-1]
k--
}
resBytes = append(resBytes, charByte)
}
res := ""
if len(resBytes) <= remain {
res = strings.TrimLeft(string(resBytes), "0")
} else {
res = strings.TrimLeft(string(resBytes[:remain]), "0")
}
if res == "" {
return "0"
}
return res
}