[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 题目讲解汇总(持续更新中...)

相关文章
相关标签/搜索