給定一個以字符串表示的非負整數 num,移除這個數中的 k 位數字,使得剩下的數字最小,其中java
首先咱們要了解一個關於數學的前置知識,對於兩個相同長度的數字序列,最左邊不一樣的數字決定了這兩個數字的大小,例如,對於 A = 1axxxA = 1axxx,B = 1bxxxB = 1bxxx,若是 a > b,則 A > Bgit
基於此,咱們能夠知道,若要使得剩下的數字最小,須要保證靠前的數字儘量小算法
若是使用暴力法,那思路就是:app
須要注意的是,若是給定的數字是一個單調遞增的數字,那麼咱們的算法會永遠選擇不丟棄。這個題目中要求的,咱們要永遠確保丟棄 k 個數字,所以思路還應該稍加修改:ui
然而暴力的實現複雜度最差會達到 O(nk)(考慮整個數字序列是單調不降的),所以咱們須要加速這個過程code
能夠用一個棧維護當前的答案序列,棧中的元素表明截止到當前位置,刪除不超過 k 次個數字時,所能獲得的最小整數。根據以前的討論:在使用 k 個刪除次數以前,棧中的序列從棧底到棧頂單調不降。所以,對於每一個數字,若是該數字小於棧頂元素,咱們就不斷地彈出棧頂元素,直到rem
上述步驟結束後咱們還須要針對一些狀況作額外的處理:字符串
class Solution { public String removeKdigits(String num, int k) { Deque<Character> deque = new LinkedList<>(); for(int i = 0; i < num.length(); i++) { while(!deque.isEmpty() && k > 0 && deque.peekLast() > num.charAt(i)) { deque.pollLast(); k--; } deque.offerLast(num.charAt(i)); } for(int i = 0; i < k; i++) { deque.pollLast(); } StringBuilder str = new StringBuilder(); boolean leadingZero = true; while(!deque.isEmpty()) { char digist = deque.pollFirst(); if(leadingZero && digist == '0') { continue; } leadingZero = false; str.append(digist); } return str.length() == 0 ? "0" : str.toString(); } }