Category | Difficulty | Likes | Dislikes |
---|
algorithms | Medium (27.00%) | 181 | - |
Tags
segment-tree
| line-sweep
Companies
Unknown
给定一个编码字符串 S
。请你找出 解码字符串 并将其写入磁带。解码时,从编码字符串中 每次读取一个字符 ,并采取以下步骤:
- 如果所读的字符是字母,则将该字母写在磁带上。
- 如果所读的字符是数字(例如
d
),则整个当前磁带总共会被重复写 d-1
次。
现在,对于给定的编码字符串 S
和索引 K
,查找并返回解码字符串中的第 K
个字母。
示例 1:
1
2
3
4
5
| 输入:S = "leet2code3", K = 10
输出:"o"
解释:
解码后的字符串为 "leetleetcodeleetleetcodeleetleetcode"。
字符串中的第 10 个字母是 "o"。
|
示例 2:
1
2
3
4
| 输入:S = "ha22", K = 5
输出:"h"
解释:
解码后的字符串为 "hahahaha"。第 5 个字母是 "h"。
|
示例 3:
1
2
3
4
| 输入:S = "a2345678999999999999999", K = 1
输出:"a"
解释:
解码后的字符串为 "a" 重复 8301530446056247680 次。第 1 个字母是 "a"。
|
提示:
2 <= S.length <= 100
S
只包含小写字母与数字 2
到 9
。S
以字母开头。1 <= K <= 10^9
- 题目保证
K
小于或等于解码字符串的长度。 - 解码后的字符串保证少于
2^63
个字母。
Discussion | Solution
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
| // @lc code=start
impl Solution {
/// ## 解题思路
/// 1. 编码字符串 "apple6"中的第24个元素和第4个元素相同,
/// 即 k(24) % l(5);
/// 2. 先正向遍历编码字符串,计算解码字符串有效长度`decode_len`, 长度只用计算到>=k时为止;
/// 3. 从有效长度的编码字符串下标开始, 逆序遍历待解码字符串, 反向更新解码字符串长度,
/// 此时如果为重复数字, 可根据1中的原理, 缩小k % l;
/// 4. 如果k % 解码字符串长度==0, 则当前字符为第k个字符;
pub fn decode_at_index(s: String, k: i32) -> String {
let mut sb = s.as_bytes();
let mut k = k as usize;
let mut decode_len = 0; //解码字符串的长度
// 正向遍历编码字符串,计算有效的解码字符串长度
let mut off = 0;
while off < sb.len() {
let c = sb[off];
if c.is_ascii_digit() {
decode_len *= (c - b'0') as usize;
if decode_len >= k {
break;
}
} else {
decode_len += 1;
if decode_len == k {
return char::from(c).to_string();
}
}
off += 1;
}
//逆序求取第k个解码字符
for &c in sb[..=off].iter().rev() {
k %= decode_len;
if k == 0 && c.is_ascii_alphabetic() {
return char::from(c).to_string();
}
if c.is_ascii_digit() {
let n = (c - b'0') as usize;
decode_len /= n;
} else {
decode_len -= 1;
}
}
return "".to_string();
}
}
// @lc code=end
|