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。
相关推荐
地平线开发者2 小时前
SparseDrive 模型导出与性能优化实战
算法·自动驾驶
董董灿是个攻城狮3 小时前
大模型连载2:初步认识 tokenizer 的过程
算法
地平线开发者3 小时前
地平线 VP 接口工程实践(一):hbVPRoiResize 接口功能、使用约束与典型问题总结
算法·自动驾驶
罗西的思考3 小时前
AI Agent框架探秘:拆解 OpenHands(10)--- Runtime
人工智能·算法·机器学习
HXhlx6 小时前
CART决策树基本原理
算法·机器学习
Wect7 小时前
LeetCode 210. 课程表 II 题解:Kahn算法+DFS 双解法精讲
前端·算法·typescript
颜酱8 小时前
单调队列:滑动窗口极值问题的最优解(通用模板版)
javascript·后端·算法
Gorway14 小时前
解析残差网络 (ResNet)
算法
拖拉斯旋风14 小时前
LeetCode 经典算法题解析:优先队列与广度优先搜索的巧妙应用
算法
Wect14 小时前
LeetCode 207. 课程表:两种解法(BFS+DFS)详细解析
前端·算法·typescript