Welcome to Subscribe On Youtube
4043. Count Rotations With Exactly K Equal Adjacent Pairs
Description
You are given a string s of length n and an integer k.
A cyclic rotation of s is obtained by choosing a prefix of s whose length is between 0 and n - 1 (inclusive), and moving it to the end of the string while preserving the order of all characters.
For every cyclic rotation of s, let its score be the number of indices i such that 0 <= i < n - 1 and the characters at positions i and i + 1 are equal.
Return the number of cyclic rotations of s whose score equals k.
Example 1:
Input: s = "aab", k = 1
Output: 2
Explanation:
The cyclic rotations of s are:
"aab": The characters at positions 0 and 1 are equal, soscore = 1."aba": No two adjacent characters are equal, soscore = 0."baa": The characters at positions 1 and 2 are equal, soscore = 1.
Since score equals k for 2 cyclic rotations of s, the answer is 2.
Example 2:
Input: s = "abca", k = 0
Output: 1
Explanation:
The cyclic rotations of s are:
"abca": No two adjacent characters are equal, soscore = 0."bcaa": The characters at positions 2 and 3 are equal, soscore = 1."caab": The characters at positions 1 and 2 are equal, soscore = 1."aabc": The characters at positions 0 and 1 are equal, soscore = 1.
Since score equals k for only 1 cyclic rotation of s, the answer is 1.
Constraints:
2 <= n == s.length <= 100sonly consists of lowercase English letters.0 <= k <= n - 1
Solutions
Solution 1: Simulation
Thinking
A cyclic left shift changes only the adjacent pairs at the two ends; equalities in the middle stay. Rebuilding the string for every rotation would be quadratic.
Compute the score of the original string, then in $O(1)$ subtract the lost head pair and add the new tail pair, counting how often the score equals $k$.
Indices modulo $n$ let all $n$ rotations run on the original string.
Let $n$ be the length of the string. First compute the score of the original string $s$, i.e. the number of indices $i$ such that $s[i] = s[i + 1]$ ($0 \leq i < n - 1$). If $\textit{score} = k$, increment the answer by $1$.
Then start from the original string and cyclically shift it left by one character, $n - 1$ times in total. On the $t$-th shift ($t = 0, 1, \ldots, n - 2$), the character moved to the end is $s[t]$, and the score changes in only two places:
- the adjacent pair at the front disappears, namely $s[t]$ and $s[t + 1]$;
- a new adjacent pair appears at the end, namely $s[t - 1]$ and $s[t]$.
All indices are taken modulo $n$. Thus $\textit{score}$ can be updated in $O(1)$ time, and we count the cyclic rotations whose score equals $k$.
The time complexity is $O(n)$ and the space complexity is $O(1)$, where $n$ is the length of the string $s$.
-
class Solution { public int countRotations(String s, int k) { int n = s.length(); int score = 0; for (int i = 0; i < n - 1; i++) { score += s.charAt(i) == s.charAt(i + 1) ? 1 : 0; } int ans = score == k ? 1 : 0; for (int i = n; i < n * 2 - 1; i++) { score += s.charAt(i % n) == s.charAt((i - 1) % n) ? 1 : 0; score -= s.charAt(i % n) == s.charAt((i + 1) % n) ? 1 : 0; ans += score == k ? 1 : 0; } return ans; } } -
class Solution { public: int countRotations(string s, int k) { int n = s.size(); int score = 0; for (int i = 0; i < n - 1; i++) { score += s[i] == s[i + 1]; } int ans = score == k; for (int i = n; i < n * 2 - 1; i++) { score += s[i % n] == s[(i - 1) % n]; score -= s[i % n] == s[(i + 1) % n]; ans += score == k; } return ans; } }; -
class Solution: def countRotations(self, s: str, k: int) -> int: n = len(s) score = sum(a == b for a, b in pairwise(s)) ans = int(score == k) for i in range(n, n * 2 - 1): score += int(s[i % n] == s[(i - 1) % n]) score -= int(s[i % n] == s[(i + 1) % n]) ans += int(score == k) return ans -
func countRotations(s string, k int) int { n := len(s) score := 0 for i := 0; i < n-1; i++ { if s[i] == s[i+1] { score++ } } ans := 0 if score == k { ans++ } for i := n; i < n*2-1; i++ { if s[i%n] == s[(i-1)%n] { score++ } if s[i%n] == s[(i+1)%n] { score-- } if score == k { ans++ } } return ans } -
function countRotations(s: string, k: number): number { const n = s.length; let score = 0; for (let i = 0; i < n - 1; i++) { score += s[i] === s[i + 1] ? 1 : 0; } let ans = score === k ? 1 : 0; for (let i = n; i < n * 2 - 1; i++) { score += s[i % n] === s[(i - 1) % n] ? 1 : 0; score -= s[i % n] === s[(i + 1) % n] ? 1 : 0; ans += score === k ? 1 : 0; } return ans; }