最长重复子串
难度:
标签:
题目描述
代码结果
运行时间: 37 ms, 内存: 0.0 MB
/*
* Leetcode Problem 1062: Longest Repeating Substring
*
* Problem Statement:
* Given a string s, find out the length of the longest repeating substring(s). The repeating substring should not overlap.
*
* Approach:
* 1. Use binary search to find the maximum length of the repeating substring.
* 2. Use a hash set to store the substrings of a given length and check for repeats.
* 3. If a repeating substring is found, increase the search length; otherwise, decrease it.
*
* Using Java Streams for substring extraction and checking repeats.
*/
import java.util.HashSet;
import java.util.stream.IntStream;
public class LongestRepeatingSubstringStream {
public int longestRepeatingSubstring(String s) {
int n = s.length();
int left = 1, right = n;
while (left <= right) {
int mid = left + (right - left) / 2;
if (hasRepeatingSubstring(s, mid)) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return left - 1;
}
private boolean hasRepeatingSubstring(String s, int length) {
HashSet<String> seen = new HashSet<>();
return IntStream.range(0, s.length() - length + 1)
.mapToObj(i -> s.substring(i, i + length))
.anyMatch(substring -> !seen.add(substring));
}
}
解释
方法:
这个题解采用了二分搜索的方法来寻找最长重复子串的长度。算法的基本思想是,通过二分搜索在可能的子串长度范围内查找,利用一个辅助函数 `haveRepetition` 来检查给定长度 `mid` 的子串是否在字符串 `s` 中重复出现。如果有重复,增大查找范围的下限 `left`;如果没有重复,减小查找范围的上限 `right`。最终,`right` 指向的是最长的重复子串的长度。
时间复杂度:
O(n log n)
空间复杂度:
O(n)
代码细节讲解
🦆
为什么在二分搜索中,当发现有重复的子串时选择增大下限`left`而在无重复时减小上限`right`?
▷🦆
在`haveRepetition`函数中,如何确保在检查子串的过程中不会漏掉任何可能的重复子串?
▷🦆
哈希集合`hSet`存储所有长度为`mid`的子串时,为什么不会出现内存溢出,尤其在处理非常长的字符串时?
▷🦆
在二分搜索中使用`(left + right + 1) // 2`而不是`(left + right) // 2`来计算`middle`的原因是什么?
▷