3307: Find-the-K-th-Character-in-String-Game-II
Hard
table of contents
The intuition is, to have constraints as large as
1 <= k <= 10^14, there has to be some pattern that
exists allowing us to retrieve the kth character
quickly.
You can see this come up in the example listed below, where you have input:
k=10operations=[1, 0]
After 4 operations, we have this:
a|b|a|b|b|c|b|c|a|b| a| b| b| c| b| c
0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15
where the numbers below denote the letters respective index.
While looking at the letters and their respective
index, a pattern begins to reveal itself. Take index
11 as an example:
- index
11came from index3after operation0
a|b|a|*b*|b|c|b|c -> a|b| a|* b*| b| c| b| c
0|1|2|*3*|4|5|6|7 -> 8|9|10|*11*|12|13|14|15
- index
3came from index1after operation0
a|*b* -> a|*b*
0|*1* -> 2|*3*
- index
1came from index0after operation1
*a* -> *b*
*0* -> *1*
If we write 11 into binary, 0b1011, and
relate the position of each 1 to an operation, for
example:
0b1011 & 0b0001 = 0b0001so the11thdigit getsoperation[0 % 2] = 10b1011 & 0b0010 = 0b0010so the11thdigit getsoperation[1 % 2] = 00b1011 & 0b0100 = 0b0100so the11thdigit does not getoperation[2 % 2] = 10b1011 & 0b1000 = 0b1000so the11thdigit getsoperation[3 % 2] = 0which mirrors the operations and the order of the operations thekthdigit was placed through.
TLDR:
After n operations, word will be of length
2^n. We know that the:
- first
2^(n-1)characters was not affected by thenthoperation - last
2^(n-1)characters was the result of thenthoperation on the first2^(n-1)characters
Given their respective indices:
- the first
2^(n-1)characters will have thenthbit set to0 - the last
2^(n-1)characters will have thenthbit set to1
Using an inductive proof, we can show that the nth bit
being set to 1 means that the respective operation has been
done on the kth character.
code
class Solution {
public:
char kthCharacter(long long k, vector<int>& operations) {
char ans = 'a';
int index = 0;
k -= 1;
while (k > 0) {
if (k % 2 == 1 && operations[index] == 1) {
if (ans-'a' == 25) {
ans = 'a';
} else {
ans = ans+1;
}
}
index = (index + 1) % operations.size();
k >>= 1;
}
return ans;
}
};