Leetcode 402.移掉k位数字

移调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。

题解:

从高位开始走,如果下一个数字比当前数字小,且要删除的数字次数每用完,则删除当前位置的数字,且继续向前比较,这样总能得到一个较小的序列。

具体来讲:

利用桟维持一个递增的序列,也就是说将字符串中字符依次入栈,如果当前字符比栈顶元素小,并且还可以继续删除元素,那么就将栈顶元素移掉,且继续向下一个栈顶元素比较,尽量维持序列递增,也可以算是一个贪心思想。最后移除字符串首部的所有 0 ,如果此时发现剩余的字符全为0,则输入 0 ,否则取非0 开始的前 num.length() - k 个元素构成一个序列即可。

由于最后要移除前面的 0 元素,可以用双端队列实现;

考虑到字符可以直接比较大小,所有用char[] 数组来模拟桟较为方便,最后从头往后查找定位第一个非0 元素即可。

 1 class Solution {
 2     public String removeKdigits(String num, int k) {
 3         if (k <= 0) {
 4             return num;
 5         }
 6         if (num.length() == 0 || k >= num.length()) {
 7             return "0";
 8         }
 9         int digits = num.length() - k;// 输出字符串的长度
10         char[] stk = new char[num.length()];// 模拟桟
11         int top = 0;// 记录栈顶元素的下一个位置
12         for (int i = 0; i < num.length(); i++) {// 遍历所有元素
13             char c = num.charAt(i);
14             while (top > 0 && stk[top - 1] > c && k > 0) {// 如果当前元素比栈顶元素小,则出栈
15                 top--;
16                 k--;
17             }
18             stk[top++] = c; // 将当前元素压桟
19         }
20         // 从头开始查找头个不为0的元素位置
21         int idx = 0;
22         while (idx < digits && stk[idx] == '0') {
23             idx++;
24         }
25         return idx == digits ? "0" : new String(stk, idx, digits - idx); //如果0的长度=所需长度(即剩下的都是0)则输出0,否则输出前digits长度的字符串
26     }
27 }

猜你喜欢

转载自www.cnblogs.com/kexinxin/p/10236747.html