移掉 K 位數字
給定一個以字串表示的非負整數 num,移除這個數中的 k 位數字,使得剩下的數字最小,其中
解題思路
首先我們要了解一個關於數學的前置知識,對於兩個相同長度的數字序列,最左邊不同的數字決定了這兩個數字的大小,例如,對於 A = 1axxxA = 1axxx,B = 1bxxxB = 1bxxx,如果 a > b,則 A > B
基於此,我們可以知道,若要使得剩下的數字最小,需要保證靠前的數字儘可能小
如果使用暴力法,那思路就是:
- 從左到右遍歷
- 對於每一個遍歷到的元素,前一個元素比當前元素大,則丟棄前一個元素,否則保留前一個元素
需要注意的是,如果給定的數字是一個單調遞增的數字,那麼我們的演算法會永遠選擇不丟棄。這個題目中要求的,我們要永遠確保丟棄 k 個數字,因此思路還應該稍加修改:
- 每次丟棄一次,k 減去 1。當 k 減到 0 ,我們可以提前終止遍歷
- 而當遍歷完成,如果 k 仍然大於 0。不妨假設最終還剩下 x 個需要丟棄,那麼我們需要選擇刪除末尾 x 個元素
然而暴力的實現複雜度最差會達到 O(nk)(考慮整個數字序列是單調不降的),因此我們需要加速這個過程
可以用一個棧維護當前的答案序列,棧中的元素代表截止到當前位置,刪除不超過 k 次個數字時,所能得到的最小整數。根據之前的討論:在使用 k 個刪除次數之前,棧中的序列從棧底到棧頂單調不降。因此,對於每個數字,如果該數字小於棧頂元素,我們就不斷地彈出棧頂元素,直到
- 棧為空
- 新的棧頂元素不大於當前數字
- 已經刪除了 k 位數字
上述步驟結束後我們還需要針對一些情況做額外的處理:
- 如果我們刪除了 m 個數字且 m<k,我們需要從序列尾部刪除額外的 k-m 個數字
- 如果最終的數字序列存在前導零,我們要刪去前導零
- 如果最終數字序列為空,我們應該返回 0
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();
}
}
相關文章
- LeetCode 402 移掉K位數字 HERODING的LeetCode之路LeetCode
- 402. 移掉K位數字 (按位考慮 貪心)
- 2^k進位制數
- 1106: 找第K位數
- 移除K個數字
- 1082. 數字遊戲 (數位DP)遊戲
- 對十進位制數字的按位輸出,取反,並求其位數
- 1295 統計位數為偶數的數字
- JZ-070-數字序列中的某一位數字
- java.sql.SQLException: 數字溢位JavaSQLException
- 打家劫舍+數字範圍按位與
- 統計位數為偶數的數字(C++)C++
- SQL 判斷欄位是否以數字開頭或者包含數字SQL
- 使用 Haskell 將十進位制數字轉成羅馬數字Haskell
- 分治與遞迴-找k個臨近中位數的數遞迴
- 牛客網測試題 把十六進位制數字轉換為十進位制數字
- 劍指 Offer 44. 數字序列中某一位的數字
- 數字每三位加逗號
- 【java】隨機生成6位的數字Java隨機
- leedcode-數字轉換為十六進位制數
- [知春路-數字聯盟]火爆招聘PHP開發!!!!!薪酬15K-30KPHP
- python中如何取數字的後幾位Python
- 找出陣列中第 k 大的數字及其出現次數陣列
- 根據數字二進位制下 1 的數目排序排序
- 羅馬數字轉換成十進位制
- 將數字的每一位分離(Dome)
- 如何生成隨機不重複的11位數字隨機
- 數字陣列最值,總和,平均,中位數 未完待續陣列
- LeetCode 1837[K進製表示下的各位數字總和]LeetCode
- 無單位數字和行高 —— 別說你懂CSS相對單位CSS
- 2022-07-11:給定n位長的數字字串和正數k,求該子符串能被k整除的子串個數。 (n<=1000,k<=100)字串
- 雙重按位非運算子 ~~ 對數字取整
- Python對數字的千分位處理方式Python
- 驗證二進位制數字正規表示式
- 正則提取車牌最後一位數字
- JavaScript數字每隔三位加一個逗號JavaScript
- JavaScript數字千分位格式化JavaScript
- 寫一個方法,當給定數字位數不足8位時,則在左邊補充0以補足8位數的方法