1. 程式人生 > >Leetcode 402.移掉k位數字

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 }