主要思路
当一段字符串重复很多次时,不管k多大,结果都和k = k%size是一样的,举个例子:S = “apple5”;解码后的字符串是appleapple…一共重复5次,长度为25,当k = 24时,k%5 = 4,也就是k=4和k=24结果是一样的,都是字符 l
我们首先求出解码后字符串的长度,然后从后往前遍历原字符串,如果遇到的是数字n,则当前解码后字符串的长度decLen除以n的结果就是前一阶段字符串的长度;也就是说前一段字符串重复了n次得到当前解码后的字符串;比如原字符串s = apple5,解码后字符串长度为25,我们从后往前遍历s,首先是5,是数字,说明原来字符串的长度就是25/5 = 5。这样不断更新decLen;
如果遇到的是字母,则decLen减去1即可。
其他细节主要看代码吧 可以手动模拟一下更好理解
#include <iostream>
#include <cstdio>
#include <vector>
#include <stack>
#include <algorithm>
#include <set>
#include <map>
using namespace std;
class Solution {
public:
string decodeAtIndex(string S,int K) {
string str = "";
long decLen = 0;//编码后字符串的长度
//先求出编码后字符串的长度
for(char ch:S) {
if(isdigit(ch)) {
decLen = decLen * (ch-'0');
}
else {
decLen++;
}
}
//从后往前遍历原字符串
int n = S.length();
for(int i = n-1;i>=0;i--) {
//例如apple5 编码后长度为25,当k等于24时,第一次循环后decLen变为5,
//24%5==4,即k = 24和k = 4的结果是一样的
K %= decLen;
if(K==0&&isalpha(S[i])) {//k最后一定等于0,decLen会不断更新
return str+=S[i];//(string) ""+S[i];//把字符转成字符串形式
}
//如果是数字就要重新更新decLen的大小
//字母的话,decLen长度减1即可
if(isdigit(S[i])) {
decLen /= (S[i]-'0');
}
else {
decLen--;//逐渐定位那个结构字母
}
}
return str;
}
};
int main(){
Solution sol;
string s = "a2b3c4d5e6f7g8h9";
cout<<sol.decodeAtIndex(s,10);//c
return 0;
}