将单词恢复初始状态所需的最短时间 II
难度:
标签:
题目描述
You are given a 0-indexed string word
and an integer k
.
At every second, you must perform the following operations:
- Remove the first
k
characters ofword
. - Add any
k
characters to the end ofword
.
Note that you do not necessarily need to add the same characters that you removed. However, you must perform both operations at every second.
Return the minimum time greater than zero required for word
to revert to its initial state.
Example 1:
Input: word = "abacaba", k = 3 Output: 2 Explanation: At the 1st second, we remove characters "aba" from the prefix of word, and add characters "bac" to the end of word. Thus, word becomes equal to "cababac". At the 2nd second, we remove characters "cab" from the prefix of word, and add "aba" to the end of word. Thus, word becomes equal to "abacaba" and reverts to its initial state. It can be shown that 2 seconds is the minimum time greater than zero required for word to revert to its initial state.
Example 2:
Input: word = "abacaba", k = 4 Output: 1 Explanation: At the 1st second, we remove characters "abac" from the prefix of word, and add characters "caba" to the end of word. Thus, word becomes equal to "abacaba" and reverts to its initial state. It can be shown that 1 second is the minimum time greater than zero required for word to revert to its initial state.
Example 3:
Input: word = "abcbabcd", k = 2 Output: 4 Explanation: At every second, we will remove the first 2 characters of word, and add the same characters to the end of word. After 4 seconds, word becomes equal to "abcbabcd" and reverts to its initial state. It can be shown that 4 seconds is the minimum time greater than zero required for word to revert to its initial state.
Constraints:
1 <= word.length <= 106
1 <= k <= word.length
word
consists only of lowercase English letters.
代码结果
运行时间: 81 ms, 内存: 16.8 MB
/*
* 思路:
* 1. 利用Java Streams进行操作。
* 2. 创建一个Stream来处理字符串操作并判断何时恢复到初始状态。
*/
import java.util.stream.Stream;
public class Solution {
public int restoreWord(String word, int k) {
final int n = word.length();
return Stream.iterate(word, w -> w.substring(k) + w.substring(0, k))
.limit(n)
.mapToInt(w -> w.equals(word) ? 1 : 0)
.reduce(0, Integer::sum);
}
}
解释
方法:
此题解采用二分查找的方法来确定最短时间。首先,初始化时间的可能范围为 [1, ceil(n/k)],其中 n 是字符串长度。在每次迭代中,计算中间值 c 作为当前秒数尝试,计算剩余长度 t = n - c * k。接着,尝试在字符串中找到前缀 word[:t] 和后缀 word[-t:] 的匹配位置。如果找到合适的匹配,尝试缩小时间范围;如果没有找到,增加时间尝试。最终确定出最小时间。特别注意边界条件的处理,例如 t <= 0 的情况,以及在字符串中寻找匹配的过程中的边界检查。
时间复杂度:
O(n log(n/k))
空间复杂度:
O(n)
代码细节讲解
🦆
在解法中使用二分查找的思路是基于什么原理?为什么这种方法适用于这个问题?
▷🦆
在每次二分查找迭代中,如何确定是否已经找到了合适的匹配位置?
▷🦆
题解中提到的边界条件`t <= 0`的具体含义是什么?在这种情况下应该如何处理?
▷