题目描述

✅ 1624. 两个相同字符之间的最长子字符串

image-20260929085332984

image-20260929085333100

题意分析

找到两个相同字符作为边界,求它们中间连续片段的最大长度,不包含边界字符。中间内容没有额外限制,所以只需要比较边界下标;不存在相同字符对时返回 -1。

解法:首次位置 + 右端点扫描

核心思路

[!blue]
从左到右枚举右端点 i,用 first[c] 保存字符 c 最早出现的位置。固定 i 后,合法左端点越靠前,中间长度 i - first[c] - 1 就越大,因此只需和最早的相同字符配对。

第一次遇到字符时记下下标,之后遇到它只更新答案,不覆盖首次位置。任意最优字符对的右端点都会被扫描到,而最早位置给出的长度至少不小于这对字符的长度,所以不会漏掉最优解。

题目只含 $26$ 个小写字母,使用定长数组即可。首次位置初始化为 -1,与合法下标 $0$ 区分;答案也初始化为 -1,表示还没有找到字符对。两个相同字符相邻时,中间片段为空,但长度 $0$ 仍是合法答案。

解题步骤

  1. 首次位置全部初始化为 -1。
  2. 答案初始化为 -1,依次扫描字符;首次遇到时只记录下标。
  3. 再次遇到时计算排除端点后的长度,更新答案。
  4. 返回答案。只有一个字符或所有字符互不相同时,不会产生候选,答案保持 -1。

代码实现

class Solution {
    public int maxLengthBetweenEqualCharacters(String s) {
        int[] first = new int[26];

        for (int i = 0; i < first.length; i++) {
            first[i] = -1;
        }

        // 无相同字符对时返回负一,相邻相同字符的合法答案为零。
        int answer = -1;

        for (int i = 0; i < s.length(); i++) {
            int index = s.charAt(i) - 'a';

            // 只保存最早位置,后续匹配才能得到最大间隔。
            if (first[index] == -1) {
                first[index] = i;
            } else {
                answer = Math.max(answer, i - first[index] - 1);
            }
        }

        return answer;
    }
}
func maxLengthBetweenEqualCharacters(s string) int {
    first := make([]int, 26)
    for i := range first {
        first[i] = -1
    }

    // 无相同字符对时返回负一,相邻相同字符的合法答案为零。
    answer := -1
    for i := 0; i < len(s); i++ {
        index := int(s[i] - 'a')
        // 只保存最早位置,后续匹配才能得到最大间隔。
        if first[index] == -1 {
            first[index] = i
        } else if distance := i - first[index] - 1; distance > answer {
            answer = distance
        }
    }
    return answer
}

复杂度分析

  • 时间复杂度:$O(n)$,扫描一次。
  • 空间复杂度:$O(1)$,固定 26 个字符位置。

关键点总结

[!green]

  • 最早位置不能覆盖,它决定后续最大间隔。
  • 长度公式减一,排除两个端点。
  • 无解 -1 与合法空串长度 0 不同。

易错点总结

[!yellow]

  • 每次覆盖位置:退化成只比较相邻两次出现。
  • 答案从 0 开始:无重复字符时会误报有解。
  • 使用包含端点的长度公式:把端点算进子串。

相似题目

题目 难度 关联与区别
325. 和等于 k 的最长子数组长度 中等 同样为某种状态保留最早出现位置以最大化跨度,本题状态是边界字符,原题是前缀和。
转载与许可
作者
链接 https://hgnulb.github.io/blog/2023/41281694
许可 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处!