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。
相关推荐
renhongxia128 分钟前
RAG检索增强生成:打通大模型与外部知识的通道
大数据·人工智能·算法
2501_9339232541 分钟前
双指针算法:移动零+复写零(Java)
数据结构·算法·双指针
和芯星通unicore1 小时前
卫星信号消失的地方,定位如何继续?——解密和芯星通DR 航位推算算法
人工智能·算法·gnss·智能驾驶gnss模块
邵奈一2 小时前
让WorkBuddy用上OpenCode免费模型:Magpie小白教程
算法
人工智能培训2 小时前
边缘AI与大模型轻量化:让智能跑进每一个终端
大数据·人工智能·算法·重构·生活
lengxuenong3 小时前
树状数组 · 信息学学习手册3-优化LIS
c++·学习·算法
动词ing3 小时前
【题目练习】外观数列
算法
余额瞒着我当琳3 小时前
C++11,发展历史浅谈,初始化列表和对象初始化,右值引用和移动语义
java·开发语言·c++·算法
suhan3 小时前
【数据结构】六、图:4.图的遍历(深度优先算法DFS、广度优先算法BFS)
数据结构·算法·排序算法