單調棧系列-Leetcode 402. 移掉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。

解題報告

爲了使得剩下的數字最小,最好的策略是儘可能讓高位的數字小一些。
所以維護一個 單調遞增棧,當前元素小於棧頂元素時,將棧頂元素出棧直到當前元素大於等於棧頂元素【當然這個過程需要保證出棧的元素個數小於等於 k 】。

最後將棧中元素取出【當然需要保證刪除的元素達到 k,如果當前刪除的元素小於 k,則依次將棧中元素彈出,直到達到 k】。

另外需要注意一點是,由於在棧底的是數字的高位,所以在棧爲空時,如果即將入棧的元素爲 0,那麼跳過入棧操作。

實現代碼

class Solution{
    public:
        string removeKdigits(string num, int k) {
            stack<char> s;
            for (int i = 0; i < num.size(); i++)
            {
                while (!s.empty() && s.top() > num[i] && k)
                {
                    s.pop();
                    k--;
                }
                if (s.empty() && num[i] == '0')
                    continue;//跳過前置0
                s.push(num[i]);
            }
            string result;
            while (!s.empty())
            {
                if (k > 0)//當還要再移除數字的時候:從此時單調遞增棧的top部刪去數字
                    k--;
                else if (k == 0)//當不用再移除數字的時候:把字符串取出來到result
                    result += s.top();

                s.pop();	
            }
            reverse(result.begin(), result.end());//stl中的reverse函數
            return result == "" ? "0" : result;
        }
};

單調棧其實不一定要新創建一個棧,比如下面這種實現。

class Solution {
    public:
        string removeKdigits(string num, int k){
            string result;
            for (int i = 0; i < num.size(); i++){
                while (result.size() && k&&result.back() > num[i]){
                    result.pop_back();
                    k--;
                }
                if (result.size() == 0 && num[i] == '0')
                    continue;
                result+=num[i];
            }
            // 注意:這裏必須同時滿足!result.empty(),因爲有可能因爲前置0的原因而跳過某些元素。前置0放到數字開頭是沒有用途的。
            while (k > 0 && !result.empty()){
                result.pop_back();
                k--;
            }
            return result == "" ? "0" : result;
        }
};

[2]^{[2]}

參考資料

[1] Leetcode 402. 移掉K位數字
[2] 題解區: Smart_Shelly

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章