解题思路
这是一个字符串前缀的最长重复词问题。需要找到每个前缀的最长重复词,并计算所有长度之和。
关键点:
- 重复词必须是真前缀
- 原串必须是重复词两次的前缀
- 使用动态规划记录每个位置的最长重复词长度
- 优化字符串匹配过程
算法步骤:
- 找到与首字符相同的所有位置
- 从后向前检查每个可能的重复词
- 验证重复词的有效性
- 累加所有前缀的最长重复词长度
代码
#include<bits/stdc++.h>
using namespace std;
class Periods {
public:
long long getLongest(int n, string s) {
vector<long long> ans(n, 0);
char startChar = s[0];
vector<int> startIndex;
// 找到所有与首字符相同的位置
for (int i = 1; i < n; i++) {
if (s[i] == startChar) {
startIndex.push_back(i);
}
}
// 从后向前处理每个可能的起始位置
for (int i = startIndex.size() - 1; i >= 0; i--) {
int index = startIndex[i];
ans[index] = index;
long long ansTemp = index;
int temp = 1;
index++;
while (index < n && (temp + 1) * 2 <= (index + 1)
&& s[index] == s[temp]) {
ans[index] = max(ans[index], ansTemp);
index++;
temp++;
}
}
// 计算总和
return accumulate(ans.begin(), ans.end(), 0LL);
}
};
import java.util.*;
public class Periods {
public long getLongest(int n, String s) {
// 初始化答案数组
long[] ans = new long[n];
char startChar = s.charAt(0);
List<Integer> startIndex = new ArrayList<>();
// 找到所有与首字符相同的位置
for (int i = 1; i < n; i++) {
if (s.charAt(i) == startChar) {
startIndex.add(i);
}
}
// 从后向前处理每个可能的起始位置
for (int i = startIndex.size() - 1; i >= 0; i--) {
int index = startIndex.get(i);
ans[index] = index;
long ansTemp = index;
int temp = 1;
index++;
while (index < n && (temp + 1) * 2 <= (index + 1)
&& s.charAt(index) == s.charAt(temp)) {
ans[index] = Math.max(ans[index], ansTemp);
index++;
temp++;
}
}
// 计算总和
long sum = 0;
for (long val : ans) {
sum += val;
}
return sum;
}
}
# -*- coding:utf-8 -*-
class Periods:
def getLongest(self, n, s):
# 初始化答案数组,记录每个位置的最长重复词长度
ans = [0 for i in range(n)]
# 获取首字符
start_c = s[0]
start_index = []
# 找到所有与首字符相同的位置
for i in range(1, n):
if s[i] == start_c:
start_index.append(i)
# 从后向前处理每个可能的起始位置
for index in start_index[::-1]:
ans[index] = index
ans_temp = index
temp = 1
index += 1
# 检查是否可以继续扩展重复词
while index < n and (temp + 1) * 2 <= (index + 1) and s[index] == s[temp]:
ans[index] = max(ans[index], ans_temp)
index += 1
temp += 1
# 返回所有长度之和
return sum(ans)
算法及复杂度
- 算法:动态规划 + 字符串匹配
- 时间复杂度:,其中 是字符串长度
- 空间复杂度:,用于存储答案数组和起始位置数组