1.題目描述(難度Medium)
Given a non-negative integer num represented as a string, remove k digits from the number so that the new number is the smallest possible.
Note:
The length of num is less than 10002 and will be ≥ k.
The given num does not contain any leading zero.
Example 1:
Input: num = "1432219", k = 3
Output: "1219"
Explanation: Remove the three digits 4, 3, and 2 to form the new number 1219 which is the smallest.
Example 2:
Input: num = "10200", k = 1
Output: "200"
Explanation: Remove the leading 1 and the number is 200. Note that the output must not contain leading zeroes.
Example 3:
Input: num = "10", k = 2
Output: "0"
Explanation: Remove all the digits from the number and it is left with nothing which is 0.
2.題目分析
題目要求是在給定的數(shù)字字符串中邀层,刪掉k個字符,使剩下的字符串的數(shù)最小。其中字符串的原始順序是不變的兔综,分析如何從前往后刪除字符是我們求解的關(guān)鍵不皆。這題反向思維可能更便于處理所有字符首装。
解題思路1:
刪掉k個字符婿着,意味著查吊,
最小的第一個字符师抄,是在0:N-k+1中選,其索引為index0漓柑,k=k-1
最小的第二個字符,是在index0+1:N-k+1中選叨吮,其索引為index1辆布,k=k-1
...
如此,直到k=0.我們把剩下的字符串追加即可茶鉴。
這種思路也可以倒過來锋玲,我們要留N-k個字符。即令k=N-k
思路同上涵叮,只是當(dāng)k=0時惭蹂,我們就得到我們需要的字符,不需要額外追加了割粮。
解題思路2:
我們可以從前往后遍歷數(shù)字盾碗,并用一個棧輔助,每次來一個數(shù)就循環(huán)判斷 棧里最后一位的是否>新來的數(shù)字穆刻,是則出棧且k=k-1, 不是則繼續(xù)遍歷下一個數(shù)字置尔,當(dāng)k=0的時候,說明我們已經(jīng)把可以移出去的數(shù)字都移出去了氢伟。剩下的數(shù)字就是我們要的榜轿。
這里要注意的一個邊界情況,可能數(shù)字有部分是按照從小到大的順序排列朵锣,這個時候k不為零谬盐,我們只要取[:-k]即可
3.解題過程
Begin(算法開始)
輸入 長度為N的數(shù)字字符串num,和刪除的個數(shù)k
IF len(num) == k: return '0'
定義輸出列表
遍歷字符串:
? while k and out and 列表末端字符>當(dāng)前字符:
? ? 末端出列
? ? k-=1
? 當(dāng)前字符加入列表
當(dāng)k不為零的時候表示當(dāng)前列表中前[:-k]使我們要的結(jié)果
當(dāng)k為零時,列表中所有的字符即為我們要串聯(lián)的數(shù)字
返回連接列表后的結(jié)果
End (算法結(jié)束)
Begin(算法開始)
輸入 長度為N的數(shù)字字符串num,和刪除的個數(shù)k
IF len(num) == k: return '0'
剩余的字符串個數(shù)為res=N-k
ind = 0
while res>0://尚沒有湊夠我們需要的字?jǐn)?shù)
? 求出num[ind:N-res+1]之間最小的數(shù) cur_min并把其加入輸出字 符串out诚些,并記錄其在num中的index
? ind = ind+index+1,res-=1
?重復(fù)上述直到res==0
return str(int(out))
End (算法結(jié)束)
具體代碼(python)已對應(yīng)實現(xiàn)飞傀,但是測試用例代碼還沒完善,如上述思路有不足之處請批評指正诬烹。