[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:

  • 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.

Example 1:

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

Example 2:

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".

Constraints:

  • 2 <= S.length <= 100
  • S will only contain lowercase letters and digits 2 through 9.
  • S starts with a letter.
  • 1 <= K <= 10^9
  • It's guaranteed that K is less than or equal to the length of the decoded string.
  • The decoded string is guaranteed to have less than 2^63 letters.

索引处的解码字符串。

给定一个编码字符串 S。请你找出 解码字符串 并将其写入磁带。解码时,从编码字符串中 每次读取一个字符 ,并采取以下步骤:

如果所读的字符是字母,则将该字母写在磁带上。
如果所读的字符是数字(例如 d),则整个当前磁带总共会被重复写 d-1 次。
现在,对于给定的编码字符串 S 和索引 K,查找并返回解码字符串中的第 K 个字母。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/decoded-string-at-index
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题意不难理解,但是介于 K 有可能会非常大,所以通过把 decoded string 完全展示出来再找第 K 个字符应该是不会通过的。

首先我展示一个较短的例子帮助理解题目的规则。比如例子二,s = "ha22", K = 5。s 全部展开应该是 hahahaha,这是因为我们一开始遍历 ha 的时候,就只是记录 ha,当我们遇到第一个 2 的时候,就要把已经记录的部分 * 2,变成 haha。当我们遇到第二个 2 的时候,我们需要把已经记录的结果再 * 2,所以结果是 hahahaha。

这道题我参考了官方题解,思路如下。首先我们还是需要计算整个字符串被 decode 过之后应有的长度,记录为 size。接着我们对 input 字符串从后往前扫描,并做 K %= size,意思是看看 K 是否能被 size 整除。

  • 如果 K 能被 size 整除且当前遍历到一个字母的话,就可以直接返回这个字母了
  • 如果当前遍历到的是一个数字,则 size /= c - '0' ,意思是可以去掉一些重复的部分
  • 如果当前遍历到的是一个字母但是 K 不能被 size 整除,则只是 size--

最后不管怎么样,都要返回一个字符串,否则会报错。

跑一个例子,如果 S = "leet2code3", K = 10,那么decode string = "leetleetcodeleetleetcodeleetleetcode", size = 36。

从后往前扫描 input 字符串的时候,一开始会碰到数字 3,同时因为 K 不等于 0 所以代码会掉入 22 行,这样 size 直接就从 36 被缩短到 12。可以这样做的道理是因为当你每遇到一个数字的时候,数字之前的字符串都会被重复若干次,比如一开始的 leet 重复两次的时候,第四个字符就一定会与第八个字符相同,所以找第八个字符就会等价于找第四个字符,结果都是 t。

然后遍历到字母 e,因为 K % size 不等于 0,所以 size--,此时 size = 12 - 1 = 11

接着遍历到字母 d,因为 K % size 不等于 0,所以 size--,此时 size = 11 - 1 = 10

接着遍历到字母 o,此时 K % size == 0,又因为此时遍历到的是一个字母,所以直接返回字母 o。

时间O(n)

空间O(1)

Java实现

 1 class Solution {
 2     public String decodeAtIndex(String S, int K) {
 3         long size = 0;
 4         int n = S.length();
 5 
 6         // find size = length of decoded string
 7         for (int i = 0; i < n; i++) {
 8             char c = S.charAt(i);
 9             if (Character.isDigit(c)) {
10                 size *= c - '0';
11             } else {
12                 size++;
13             }
14         }
15 
16         for (int i = n - 1; i >= 0; i--) {
17             char c = S.charAt(i);
18             K %= size;
19             if (K == 0 && Character.isLetter(c)) {
20                 return Character.toString(c);
21             }
22             if (Character.isDigit(c)) {
23                 size /= c - '0';
24             } else {
25                 size--;
26             }
27         }
28         return "";
29     }
30 }

 

LeetCode 题目总结

posted @ 2020-12-23 01:19  CNoodle  阅读(243)  评论(0编辑  收藏  举报