想了解更多數據結構以及算法題,可以關注微信公衆號“數據結構和算法”,每天一題爲你精彩解答。也可以掃描下面的二維碼關注
給定一個以字符串表示的非負整數 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。
我們來分析一下,上面題說的是從一個字符串num中移除k個數字,使剩下的數字最小。我們可以先從移除一個數字開始看
所以我們找出了一個規律就是,就是從左往右刪除第一個降序開始的值。
比如第一個3156,31是降序,所以刪除3;
比如第二個1563,63是降序,所以刪除6;
比如第二個3756,75是降序,所以刪除7。
如果沒有降序的,比如1234,我們就刪除最後一個,結果才能是最小。
我們再來舉一個移除兩個數字的例子
所以規律很容易發現了,就是從左往右刪除開始降序的數字,直到刪除k個爲止。或者也可以這樣理解,就是每遍歷一個數字就要判斷他前面有沒有比他大的數字,如果有就刪除,直到累計刪除k個爲止。
1,那麼這時候問題就來了,如果遍歷完了刪除的還不到k個怎麼辦呢,就像上面說的1234沒有降序的這種,我們就刪除最後的幾個數字,湊夠k個爲止。
2,這個時候還會有一個問題,比如2014,如果我們刪除一個數字讓剩下的數字最小,我們刪除的是2,那麼結果就會變成014,所以我們還要把前導0去掉。
我們來看下代碼
public String removeKdigits(String num, int k) {
if (num.length() <= k)
return "0";
int digits = num.length() - k;
char[] stk = new char[digits];
int top = 0;
for (int i = 0; i < num.length(); i++) {
char c = num.charAt(i);
while (top > 0 && stk[top - 1] > c && k > 0) {
k--;
top--;
}
if (top < digits) {
stk[top++] = c;
} else {
k--;
}
}
int idx = 0;
while (idx < digits && stk[idx] == '0')
idx++;
return idx == digits ? "0" : new String(stk, idx, digits - idx);
}
上面代碼沒有在原始字符串上操作,而是使用了一個臨時數組stk,他會把原始字符串中的字符逐個放到stk數組中,放的時候如果發現前面有比他大的,就把前面比他大的移除掉,第13行有個判斷,如果個數達到了那麼當前值就不在添加了,在下一輪的for循環中還會進行判斷,第20行通過循環去掉前導0。