- μ΄ λ¬Έμ μ ν΅μ¬μ λ§λ€μ΄μ§ λ¬Έμμ΄μμ prefixλ₯Ό ν¨κ³Όμ μΌλ‘ μλΌλ΄λ λ°©λ²μ κ³ λ―Όνλ λ°μ μλ€.
- λ¨Όμ λ¬Έμμ΄μ ν΄μνμ¬ λ°λ³΅λ λ¬Έμμ΄μ μΌλΆ
value
μ μ§κΈκΉμ§ λμλ patternμ λ°λ³΅ν νμ repeat
λ₯Ό ꡬνμ¬ κ°κ°μ ꡬλΆλλ νλͺ© Item
μΌλ‘ λ§λ λ€.
- κ·Έλ¦¬κ³ κ° νλͺ©μ λ¬Έμμ΄ λ²μλ₯Ό κ³μ°νλ€.
- λ°λ³΅ νμ
repeat
κ° μ§μ λ νλͺ©μ κ²½μ° from
μλ μ§κΈκΉμ§μ λ¬Έμμ΄ κΈΈμ΄, to
μλ λ°λ³΅λ μ΄ κΈΈμ΄λ₯Ό κΈ°λ‘νλ€. - λ°λ³΅λ λ¬Έμμ΄μ μΌλΆ
value
κ° μ§μ λ νλͺ©μ κ²½μ° from
μλ μ§κΈκΉμ§μ λ¬Έμμ΄ κΈΈμ΄, to
μλ value
κ° λν΄μ§ μ΄ λ¬Έμμ΄μ κΈΈμ΄λ₯Ό κΈ°λ‘νλ€.
- λ§μ§λ§μΌλ‘
k
κ°μ 0-based indexλ‘ λ³ν --k
νκ³ λ€μ μμ
μ λ°λ³΅μ μΌλ‘ μννλ€. - (1)
k
λ₯Ό ν¬ν¨νλ λ²μ [from, to)
λ₯Ό κ°μ§ νλͺ©μ μ°Ύλλ€. - (2-1)
repeat
κ° μ§μ λ νλͺ©μ΄λΌλ©΄ k
μμ prefixμ κΈΈμ΄ from
μ λλ λλ¨Έμ§ k % from
λ₯Ό μλ‘μ΄ k
κ°μΌλ‘ νλ€. - κ²μν μμΉ
k
μμλ from
κΈΈμ΄ λ§νΌμ prefixκ° μμμ νμλ§νΌ λ°λ³΅λ μ μλ€. - μ΄κ²μ μλΌλ΄κ³ λλ©΄ μλ‘μ΄ index
kβ
λ κ²°κ΅ prefix λ΄λΆμ μμΉνκ² λλ€.
- (2-2)
value
κ° μ§μ λ νλͺ©μ΄λΌλ©΄ k
μμ prefixμ κΈΈμ΄ from
μ λΊ κ°μ μλ‘μ΄ k
κ°μΌλ‘ νκ³ μ΄λ₯Ό κΈ°λ°μΌλ‘ νμ¬ νλͺ©μ κ°μ μ κ·Ό item.value[k]
νμ¬ κ²°κ³Όλ‘ λλ €μ€λ€. - prefix
from
μ μλΌλ΄κ³ λλ©΄ μλ‘μ΄ index kβ
λ νμ¬ νλͺ©μ λ¬Έμμ΄ value
λ΄μ μμΉνκ² λλ€.
class Solution {
public:
struct Item {
string value;
int repeat;
long long from;
long long to;
};
string decodeAtIndex(string s, int k) {
// make items
vector<Item> items;
for (auto c : s) {
if (c >= '0' && c <= '9') {
if (items.empty()) continue;
items.push_back({{}, c - '0', 0});
} else {
if (items.empty() || items.back().repeat > 0) {
items.push_back({});
}
items.back().value += c;
}
}
// calculate range
long long prevLength = 0;
for (auto& item : items) {
item.from = prevLength;
if (item.repeat > 0) {
item.to = prevLength * item.repeat;
} else {
item.to = prevLength + item.value.length();
}
prevLength = item.to;
}
// to zero based index
--k;
int pos = 0;
while (true) {
// find matching range
for (int i = 0; i < items.size(); ++i) {
if (k >= items[i].from && k < items[i].to) {
pos = i;
break;
}
}
auto& item = items[pos];
if (item.repeat > 0) {
// repeat (remove) prefixes
k %= item.from;
} else {
// remove prefix
k -= item.from;
// index based on current range
return item.value.substr(k, 1);
}
}
// not reachable
abort();
}
};