4043. 恰好有 K 对相等相邻字符的循环移位数量
题目描述
给你一个长度为 n 的字符串 s 和一个整数 k。
s 的一次 循环移位 可以通过以下方式得到:选择 s 的一个长度在 0 到 n - 1(包含两端)之间的 前缀 ,并将其移动到字符串末尾,同时保持所有字符的相对顺序不变。
对于 s 的 每一种 循环移位,定义其 得分 为满足以下条件的下标 i 的数量:0 <= i < n - 1,且位置 i 和 i + 1 处的字符相同。
返回得分等于 k 的循环移位数量。
字符串的 前缀 是指从字符串开头开始,并延伸到字符串中某个位置的子串。
子串 是字符串中一段连续的字符序列,可以为空。
示例 1:
输入: s = "aab", k = 1
输出: 2
解释:
s 的所有循环移位为:
"aab":位置 0 和 1 处的字符相同,因此score = 1。"aba":不存在两个相邻且相同的字符,因此score = 0。"baa":位置 1 和 2 处的字符相同,因此score = 1。
共有 2 种 s 的循环移位,其 score 等于 k,因此答案为 2。
示例 2:
输入: s = "abca", k = 0
输出: 1
解释:
s 的所有循环移位为:
"abca":不存在两个相邻且相同的字符,因此score = 0。"bcaa":位置 2 和 3 处的字符相同,因此score = 1。"caab":位置 1 和 2 处的字符相同,因此score = 1。"aabc":位置 0 和 1 处的字符相同,因此score = 1。
只有 1 种 s 的循环移位,其 score 等于 k,因此答案为 1。
提示:
2 <= n == s.length <= 100s仅由小写英文字母组成。0 <= k <= n - 1
解法
方法一:模拟
记字符串长度为 \(n\)。我们先计算原串 \(s\) 的得分 \(\textit{score}\),即满足 \(s[i] = s[i + 1]\)(\(0 \leq i < n - 1\))的下标数量。若 \(\textit{score} = k\),则将答案加 \(1\)。
接下来从原串出发,依次循环左移一位,共进行 \(n - 1\) 次。第 \(t\) 次左移(\(t = 0, 1, \ldots, n - 2\))时,移到末尾的字符为 \(s[t]\),得分仅有两处变化:
- 失去原先首部的相邻对,即 \(s[t]\) 与 \(s[t + 1]\);
- 新增尾部的相邻对,即 \(s[t - 1]\) 与 \(s[t]\)。
其中下标对 \(n\) 取模。因此可以 \(O(1)\) 更新 \(\textit{score}\),并统计得分等于 \(k\) 的循环移位数量。
时间复杂度 \(O(n)\),空间复杂度 \(O(1)\)。其中 \(n\) 是字符串 \(s\) 的长度。
1 2 3 4 5 6 7 8 9 10 11 12 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |