本文涉及知识点
数论:质数、最大公约数、菲蜀定理
LeetCode880. 索引处的解码字符串
给定一个编码字符串 s 。请你找出 解码字符串 并将其写入磁带。解码时,从编码字符串中 每次读取一个字符 ,并采取以下步骤:
如果所读的字符是字母,则将该字母写在磁带上。
如果所读的字符是数字(例如 d),则整个当前磁带总共会被重复写 d-1 次。
现在,对于给定的编码字符串 s 和索引 k,查找并返回解码字符串中的第 k 个字母。
示例 1:
输入:s = “leet2code3”, k = 10
输出:“o”
解释:
解码后的字符串为 “leetleetcodeleetleetcodeleetleetcode”。
字符串中的第 10 个字母是 “o”。
示例 2:
输入:s = “ha22”, k = 5
输出:“h”
解释:
解码后的字符串为 “hahahaha”。第 5 个字母是 “h”。
示例 3:
输入:s = “a2345678999999999999999”, k = 1
输出:“a”
解释:
解码后的字符串为 “a” 重复 8301530446056247680 次。第 1 个字母是 “a”。
提示:
2 <= s.length <= 100
s 只包含小写字母与数字 2 到 9 。
s 以字母开头。
1 <= k <= 109
题目保证 k 小于或等于解码字符串的长度。
解码后的字符串保证少于 263 个字母。
数论
str记录所有字符串,int数组d记录所有数字。比如:ab3e1,则str = {“ab”,“e”},d = {3,1}。
long long数组len[i]记录各操作后的字符串的长度。
len[0]=0
{
l
e
n
[
2
i
+
1
]
=
l
e
n
[
2
i
]
+
s
t
r
[
i
]
.
l
e
n
g
t
h
奇数
l
e
n
[
2
i
+
2
]
=
l
e
n
[
2
i
+
1
]
∗
d
[
i
]
偶数
\begin{cases} len[2i+1] = len[2i] + str[i].length && 奇数\\ len[2i+2] = len[2i+1]*d[i] && 偶数\\ \end{cases}
{len[2i+1]=len[2i]+str[i].lengthlen[2i+2]=len[2i+1]∗d[i]奇数偶数
f(x)函数的定义:
len[i1] > x ,且i1最小
如果i1是奇数,return str[i1/2][x-len[i1-1]]。
如果i1是偶数:return f(x % len[i1-1])。
最终调用:f(k-1)。
代码
核心代码
class Solution {
public:
string decodeAtIndex(string s, int k) {
const int N = s.length();
vector<string> strs;
vector<int> d;
for (int i = 0; i < N;) {
string str;
while ((i < N) && isalpha(s[i])) {
str += s[i]; i++;
}
strs.emplace_back(str);
if ((i < N) && isdigit(s[i])) {
d.emplace_back(s[i] - '0'); i++;
}
}
if (d.size() < strs.size()) {
d.emplace_back(1);
}
vector<long long> lens = { 0 };
for (int i = 0; i < strs.size(); i++) {
lens.emplace_back(lens.back() + strs[i].length());
lens.emplace_back(lens.back() * d[i]);
}
function<char(int)> f = [&](long long x) {
int i1 = upper_bound(lens.begin(), lens.end(), x)-lens.begin();
if (i1 & 1) {
return strs[i1 / 2][x - lens[i1 - 1]];
}
return f(x % lens[i1 - 1]);
};
return string(1,f(k - 1));
}
};
单元测试
string s;
int k;
TEST_METHOD(TestMethod1)
{
s = "a1", k = 1;
auto res = Solution().decodeAtIndex(s, k);
AssertEx(string("a"), res);
}
TEST_METHOD(TestMethod2)
{
s = "abc", k = 1;
auto res = Solution().decodeAtIndex(s, k);
AssertEx(string("a"), res);
}
TEST_METHOD(TestMethod11)
{
s = "leet2code3", k = 10;
auto res = Solution().decodeAtIndex(s,k);
AssertEx(string("o"), res);
}
TEST_METHOD(TestMethod12)
{
s = "ha22", k = 5;
auto res = Solution().decodeAtIndex(s, k);
AssertEx(string("h"), res);
}
TEST_METHOD(TestMethod13)
{
s = "a2345678999999999999999", k = 1;
auto res = Solution().decodeAtIndex(s, k);
AssertEx(string("a"), res);
}
扩展阅读
我想对大家说的话 |
---|
工作中遇到的问题,可以按类别查阅鄙人的算法文章,请点击《算法与数据汇总》。 |
学习算法:按章节学习《喜缺全书算法册》,大量的题目和测试用例,打包下载。重视操作 |
有效学习:明确的目标 及时的反馈 拉伸区(难度合适) 专注 |
闻缺陷则喜(喜缺)是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。 |
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。 |
如果程序是一条龙,那算法就是他的是睛 |
失败+反思=成功 成功+反思=成功 |
视频课程
先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771
如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176
测试环境
操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。