1. 程式人生 > 實用技巧 >2020-12-15 單調遞增的數字

2020-12-15 單調遞增的數字

題目


解題方法

貪心法

採用貪心的思想解決該問題,對於輸入\(N\),先將其轉換為字串\(digit\)(方便索引與修改)。
解決該問題的方法是從高位向低位遍歷,直至碰到第一個元素\(digit[i]\),使得\(digit[i]>=digit[i-1]\),將\(digit[i-1]\)的值減去\(1\),再將低位上的數都改為\(9\)。但是,可能碰到這種情況:\(digit[i-1]\)減掉\(1\)後使得\(digit[i-1]<digit[i-2]\),因而破壞了單調遞增的條件,因此在進行了上述操作之後,還要往前回溯直到找到下標\(j\left(0<j<digit.size()\right)\)

使得\(digit[j]-1 >= digit[j-1]\),然後將\(j\)之後的低位上的數都改為\(9\)

class Solution {
public:
    int monotoneIncreasingDigits(int N) {
        if (N < 10)
            return N;

        string digit = to_string(N);      // 將N轉化為字串
        int i = 1;
        while (i < digit.size() && digit[i-1] <= digit[i]) { 
            i++;            // 從高位往低位遍歷,尋找破壞單調遞增條件的元素
        }

        if (i < digit.size()) {      // 若找到了
            while (i > 0 && digit[i-1] > digit[i]) {
                digit[i-1] -= 1;    
                i--;
            }

            for (i += 1; i < digit.size(); i++) {
                digit[i] = '9';
            }
        }

        return stoi(digit);      // 將字串轉換為整數
    }
};

提交結果


總結

在解決本題時使用了貪心的思想,從高位往低位遍歷,儘可能地使得到的值最大。
在編寫程式碼時使用了兩個庫函式to_string()stoi(),這兩個函式的LLVM實現在這裡
努力看了一下實現原始碼,發現看不懂:(,待以後進一步學習C++模板等內容了再看吧。