返回
长串珍藏:探索最长重复子串算法之美
后端
2023-09-16 18:53:21
最长重复子串算法:Go语言实现
func findLongestSubstringWithKRepeat(s string, k int) int {
// 滑动窗口的左右边界
left, right := 0, 0
// 哈希表存储字符及其出现次数
charFreq := make(map[byte]int)
// 满足条件的子串长度
maxLen := 0
for right < len(s) {
// 将当前字符加入哈希表
charFreq[s[right]]++
// 统计满足条件的字符数量
cnt := 0
for _, freq := range charFreq {
if freq == k {
cnt++
}
}
// 满足条件则更新最长子串长度
if cnt == len(charFreq) {
maxLen = max(maxLen, right-left+1)
}
// 滑动窗口右边界向右移动
right++
// 如果不满足条件,则将左边界向右移动并更新哈希表
for cnt != len(charFreq) {
charFreq[s[left]]--
if charFreq[s[left]] == 0 {
delete(charFreq, s[left])
}
left++
cnt--
}
}
return maxLen
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
最长重复子串算法:Java语言实现
import java.util.HashMap;
import java.util.Map;
class Solution {
/**
* 寻找至少包含 K 个重复字符的最长子串
*
* @param s 字符串
* @param k 重复字符的数量
* @return 最长子串的长度
*/
public int findLongestSubstringWithKRepeat(String s, int k) {
// 滑动窗口的左右边界
int left = 0, right = 0;
// 哈希表存储字符及其出现次数
Map<Character, Integer> charFreq = new HashMap<>();
// 满足条件的子串长度
int maxLen = 0;
for (right = 0; right < s.length(); right++) {
// 将当前字符加入哈希表
charFreq.put(s.charAt(right), charFreq.getOrDefault(s.charAt(right), 0) + 1);
// 统计满足条件的字符数量
int cnt = 0;
for (int freq : charFreq.values()) {
if (freq == k) {
cnt++;
}
}
// 满足条件则更新最长子串长度
if (cnt == charFreq.size()) {
maxLen = Math.max(maxLen, right - left + 1);
}
// 滑动窗口右边界向右移动
right++;
// 如果不满足条件,则将左边界向右移动并更新哈希表
while (cnt != charFreq.size()) {
charFreq.put(s.charAt(left), charFreq.get(s.charAt(left)) - 1);
if (charFreq.get(s.charAt(left)) == 0) {
charFreq.remove(s.charAt(left));
}
left++;
cnt--;
}
}
return maxLen;
}
}
算法背后的思想
这两种算法都使用了滑动窗口的思想。滑动窗口是一种用于处理连续数据流的算法技术。它通过将数据流划分为固定大小的窗口,然后在窗口上执行某些操作来实现。
在寻找最长重复子串的问题中,滑动窗口的左右边界分别指向子串的起始和结束位置。算法首先将滑动窗口的右边界向右移动,并将遇到的每个字符添加到哈希表中。哈希表用于存储每个字符出现的次数。
当滑动窗口中包含了至少 K 个重复字符时,算法会更新最长子串的长度。然后,算法将滑动窗口的左边界向右移动,并将左边界处的字符从哈希表中删除。
算法不断地移动滑动窗口,直到它到达字符串的末尾。在移动过程中,算法会不断地更新最长子串的长度。最终,算法会返回最长子串的长度。
算法的复杂度
这两种算法的时间复杂度都是 O(n),其中 n 是字符串的长度。算法的空间复杂度都是 O(k),其中 k 是重复字符的数量。
结语
在这篇文章中,我们探索了两种寻找最长重复子串的算法:Go语言和Java语言的算法实现。这些算法都是基于滑动窗口的思想,它们的时间复杂度都是 O(n),空间复杂度都是 O(k)。希望这些算法能够帮助您解决实际问题,也希望您能从中学习到算法之美!