775 · 回文对

步骤 1:理解题意

给定 无重复 单词列表 words,找出所有 不同的下标对 (i, j) ,使得 words[i] + words[j] 构成回文串。

注意:

  • i 可以等于 j 吗?题目说"不同的索引对",且 words 无重复,故 i≠j。
  • 结果只需返回下标对列表,顺序不限。

步骤 2:写出暴力/朴素解法

双重循环枚举所有 (i, j),拼接后 O(L) 判断是否回文,总复杂度 O(n²·L),n≤5000 会 TLE。

步骤 3:寻找冗余与优化点

核心观察:

对于拼接串 left + right 要成回文,

  1. left后缀right前缀互为逆串;
  2. 剩余部分自身必须是回文。

预处理:

  • 把每个单词及其下标存入 HashMap<String,Integer>,O(1) 查逆串是否存在。
  • 枚举每个单词 words[i],把它拆成 prefix + suffix,共 L+1 种拆法:
    • prefix 是回文,且 suffix 的逆串存在于 words,则存在 j 使得 (j, i) 成对;
    • suffix 是回文,且 prefix 的逆串存在于 words,则存在 j 使得 (i, j) 成对。

单次检查 O(L),总复杂度 O(n·L²),n≤5000, L≤20 可过。

步骤 4:给出最优"快刷"版本

java 复制代码
public List<List<Integer>> palindromePairs(String[] words) {
    List<List<Integer>> ans = new ArrayList<>();
    Map<String, Integer> map = new HashMap<>();
    for (int i = 0; i < words.length; i++) map.put(words[i], i);

    for (int i = 0; i < words.length; i++) {
        String w = words[i];
        int L = w.length();
        for (int cut = 0; cut <= L; cut++) {
            String prefix = w.substring(0, cut);
            String suffix = w.substring(cut);
            // 情况1:prefix 是回文,找 suffix 的逆
            if (isPalindrome(prefix)) {
                String rev = new StringBuilder(suffix).reverse().toString();
                Integer j = map.get(rev);
                if (j != null && j != i) {
                    ans.add(Arrays.asList(j, i));
                }
            }
            // 情况2:suffix 是回文,找 prefix 的逆(避免重复拆空串)
            if (cut != L && isPalindrome(suffix)) {
                String rev = new StringBuilder(prefix).reverse().toString();
                Integer j = map.get(rev);
                if (j != null && j != i) {
                    ans.add(Arrays.asList(i, j));
                }
            }
        }
    }
    return ans;
}

private boolean isPalindrome(String s) {
    int l = 0, r = s.length() - 1;
    while (l < r) if (s.charAt(l++) != s.charAt(r--)) return false;
    return true;
}
  • 时间:O(n·L²)
  • 空间:O(n·L)(哈希表)
  • 可直接 copy 通过 LintCode 775。
相关推荐
林森lsjs4 分钟前
【日耕一题】5. 青春常数(17届蓝桥杯C++B组第一题)
算法·蓝桥杯
Tisfy7 分钟前
LeetCode 3838.带权单词映射:求和、取模、拼接(附python一行版)
python·算法·leetcode·字符串·题解·模拟·取模
め.13 分钟前
GJK算法实现细节
算法
AI科技星14 分钟前
第六卷:量天尺传奇(几何学)
网络·人工智能·算法·概率论·学习方法·几何学·拓扑学
Y_Bk16 分钟前
第十七届蓝桥杯C/C++A组省赛
c语言·数据结构·c++·算法·蓝桥杯
帅小伙―苏21 分钟前
力扣76最小覆盖子串
算法·leetcode
RH23121130 分钟前
2026.5.24 数据结构 KMP算法实现
数据结构·算法
江屿风33 分钟前
C++图论基础单源最短路-常规版dijkstra算法/堆优化版dijkstra算法/bellman-ford 算法/spfa 算法流食般投喂
开发语言·c++·笔记·算法·图论
浮芷.1 小时前
鸿蒙 6.1 新特性-60fps流畅人物跳跃功能算法深度解析-鸿蒙PC端正弦值计算法
算法·华为·harmonyos·鸿蒙·鸿蒙系统
AI科技星1 小时前
数术工坊·第八卷 大道归一录・番外・下篇 零界封神・万法归元终章
网络·人工智能·算法·几何学·拓扑学