移除K個數字

sas???發表於2018-03-13

LeetCode 402. Remove K Digits
已知一個使用字串表示的非負整數num,將num中的k個數字移除, 求移除k個數字後,可以獲得的最小的可能的新數字。(num不會以0開頭,num長度小於10002)

輸入 : num = “1432219” , k = 3
在去掉3個數字後得到的很多很多可能裡,如1432、4322、2219、1219、 1229...;去掉數字4、3、2得到的1219最小!

class Solution{
public:
    std::string removeKdigits(std::string num, int k){// 返回的結果用字串來表示
    }
};

分析

假設 num = 1432219 ; k = 1, 分別去掉1, 4, 3, 2, 2, 1, 9 得到數字:


8789591-243b10666e3ed7a4.png

分析與常識:
若去掉某一位數字,為了使得到的新數字最小,需要儘可能讓得到的新數字優先 最高位最小,其次次高位最小, 再其次第3位最小...

演算法設計

使用棧儲存最終結果或刪除工作,從高位向低位遍歷num,
如果遍歷的數字大於棧頂元素,則將該數字push入棧
如果小於棧頂元素則進行pop彈棧,直到棧為空或不能再刪除數字
(k==0)或棧頂小於當前元素為止。
最終棧中從棧底到棧頂儲存的數字,即為結果。


8789591-61f79632105cf1ab.png

8789591-96bd23a0fa0e36b0.png

8789591-ce47842dd24868cd.png
邊界條件

1.當所有數字都掃描完成後,k仍然>0,應該做怎樣的處理? 例如: num = 12345, k = 3 時。
2.當數字中有0出現時,應該有怎樣的特殊處理? 例如: num = 100200, k = 1 時。
3.如何將最後結果儲存為字串並返回?

class Solution{
public:
    std::string removeKdigits(std::string num, int k){
    std::vector<int> S;//使用vector當作棧(因為vector可以遍歷)
    std::string result = "";儲存最終結果的字串
    for(int i = 0;i <num.length();i++){//最高位迴圈掃描數字num
        int number = num[i] - '0';//將字元型num轉換整數;
        while(S.size() != 0 && S[S.size() -1]>number  && k>0){//當棧不空,棧頂元素大於number
            S.pop_back();
            k --;
        }
        if(number !=0 || S.size() != 0){
            S.push_back(number);
        }
    while(S.size() && k>0){//如果棧不空仍然可以刪除數字
        S.pop_back();
        k--;
    for(int i = 0;i<S.size();i++){
        result.append(1,'0'+S[i]);//轉換成字串
      }
    if(result == ""){
          result = "0";
      }
    return result;
      
    }
};

相關文章