[LeetCode] 880. Decoded String at Index 在位置座標處解碼字符串



An encoded string S is given.  To find and write the decoded string to a tape, the encoded string is read one character at a time and the following steps are taken:html

  • If the character read is a letter, that letter is written onto the tape.
  • If the character read is a digit (say d), the entire current tape is repeatedly written d-1 more times in total.

Now for some encoded string S, and an index K, find and return the K-th letter (1 indexed) in the decoded string.git

Example 1:github

Input: S = "leet2code3", K = 10
Output: "o"
Explanation:
The decoded string is "leetleetcodeleetleetcodeleetleetcode".
The 10th letter in the string is "o".

Example 2:less

Input: S = "ha22", K = 5
Output: "h"
Explanation:
The decoded string is "hahahaha".  The 5th letter is "h".

Example 3:函數

Input: S = "a2345678999999999999999", K = 1
Output: "a"
Explanation:
The decoded string is "a" repeated 8301530446056247680 times.  The 1st letter is "a".

Note:code

  1. 2 <= S.length <= 100
  2. S will only contain lowercase letters and digits 2through 9.
  3. S starts with a letter.
  4. 1 <= K <= 10^9
  5. The decoded string is guaranteed to have less than 2^63 letters.



這道題給了咱們一個加碼後的字符串,其實就是一種特殊的壓縮方式,裏面的數字表明前面全部的字符串重複的次數,又給了一個座標K,讓咱們返回還原後的字符串中K位置的子串,其實就是一個字符,可是返回類型非要是字符串。博主最開始作的時候,沒有認真讀題,將壓縮方式搞錯了兩個地方,首先博主覺得多個數字相連的話要拼成個多位數,但其實是分開的,好比例子2中的 ha22,第一個2是將 ha 重複兩次,第二個2是將 haha 重複兩次。博主犯的另外一個錯誤是覺得只重複以前的字符串部分,好比 a2b3,博主覺得後面的3只是將b重複三次,實際上是將前面的 a2b 重複三次。不認真審題的代價是慘重的,被 OJ 批的體無完膚。如今既然已經弄清楚了題意,就來想一想如何解題吧。這道題是主要是參考了大神lee215的帖子,如今不多能看到史蒂芬大神的帖子了,在後史蒂芬時代,lee215 大神獨自撐起了一片天空,有時候題既是大神出的,最高分解法仍是大神寫的,不得不令人無比崇敬。htm

怒吹一波後回到題目,你們最容易想到的方法就是直接按規律還原字符串唄,將還原後的字符串保存出來,這樣就能夠利用K來直接訪問了。這種方法博主連試都不肯意試的,OJ 是有尊嚴的,不甩你個 Time Limited Exceeded,也得來個 Memory Limited Exceeded 吧。保存解碼後的整個字符串是不現實的,可是咱們又必需要知道原字符串的座標信息,那麼惟一的選擇就是記錄解碼後字符串的長度,好比 ha22,當遍歷到a的時候,此時計數器爲2,表示當前解碼到的位置長度爲2,當遇到第一個2的時候,用當前的計數器的值乘以這個數字,即 2x2=4,說明此時解碼後的字符串長度爲4,當再遍歷到最後一個2的時候,一樣的操做,用當前計數器的值乘以這個數字,即 4x2=8,則最終的解碼後的字符串長度爲8。這種操做是能夠統計出解碼後字符串的長度的,可是咱們沒有必要統計整個的長度,由於題目只讓找第K個位置的字符,那麼咱們只須要解碼到計數器 cnt 恰好大於等於K的時候就能夠中止了。當 cnt 大於等於 K 的時候,如今的i位置不必定是所求,咱們得往前找,找到那個符合題意的第K個字符。因此須要從i位置往前遍歷,當 S[i] 是數字的時候,此時的處理就是跟以前反過來了,以前咱們遇到數字,都是乘以計數器 cnt,此時咱們應該用計數器除以這個數字,同時K應該對縮小後的 cnt 取餘。仍是拿例子2來講,當遍歷完最後一個2時,此時計數器爲8,大於 K=5 了,因此須要往前遍歷,那麼 cnt 除以2以後變爲了4,此時用K對4取餘,獲得1。而後再往前遍歷,仍是2,用 cnt 除以2以後變爲了2,此時 K=1 對2取餘,仍是1。此時再往前,遍歷到字母a,此時發現 K=1 不能整除 cnt=2,則 cnt 自減1,由於還要往前走。那麼當到達字母h時,此時 K=1 終於能夠整除 cnt=1 了,則當前的 S[i] 即爲所求,參見代碼以下:blog



解法一:遞歸

class Solution {
public:
    string decodeAtIndex(string S, int K) {
        long i = 0, cnt = 0;
        for (; cnt < K; ++i) {
            cnt = isdigit(S[i]) ? cnt * (S[i] - '0') : (cnt + 1);
        }
        while (i--) {
            if (isdigit(S[i])) {
                cnt /= (S[i] - '0');
                K %= cnt;
            } else {
                if (K % cnt == 0) return string(1, S[i]);
                --cnt;
            }
        }
        return "grandyang";
    }
};



咱們也可使用遞歸來作,其實思路都是同樣的,仍是須要一個長整型的計數器 cnt,而後遍歷原字符串S,當 S[i] 是字母的時候,且自增1後的 cnt 等於K了,說明正好找了第K個字符,直接轉爲字符串返回便可。不然遇到數字的話,仍是要乘以計數器 cnt,若大於等於K的話,則調用遞歸函數,注意這裏的S能夠用 [0, i) 之間的子串代替,能夠省些空間,固然用S也是能夠的。K的話比較 tricky,由於這裏 cnt 乘以了一個數字(大於1)才能大於等於K,因此當前的 cnt 必定是小於K的,那麼此時就有 cnt 是否能整除K兩種狀況,當 cnt 不能整除K時,好比當 cnt=2,K=5 時,就是例子2中的狀況,咱們用K對 cnt 取餘,獲得1來帶入遞歸。可是當 cnt 能夠整除K時,好比當 cnt=2,K=4 時,若直接取餘,會獲得0,直接帶入0確定時不對的,由於題目中說了K是從1開始的,因此咱們應該帶入的是 cnt 自己,那麼兩種狀況合爲一個表達式就是 (K-1)%cnt + 1。若 cnt 小於K,則乘以當前數字便可,參見代碼以下:leetcode



解法二:

class Solution {
public:
    string decodeAtIndex(string S, int K) {
        long cnt = 0;
        for (int i = 0; i < S.size(); ++i) {
            if (isalpha(S[i])) {
                if (++cnt == K) return string(1, S[i]);
            } else {
                if (cnt * (S[i] - '0') >= K) return decodeAtIndex(S.substr(0, i), (K - 1) % cnt + 1);
                cnt *= (S[i] - '0');
            }
        }
        return "grandyang";
    }
};



Github 同步地址:

https://github.com/grandyang/leetcode/issues/880



參考資料:

https://leetcode.com/problems/decoded-string-at-index/

https://leetcode.com/problems/decoded-string-at-index/discuss/157156/15-lines-clear-code

https://leetcode.com/problems/decoded-string-at-index/discuss/156747/C%2B%2BPython-O(N)-Time-O(1)-Space



LeetCode All in One 題目講解彙總(持續更新中...)

相關文章
相關標籤/搜索