336-Palindrome Pairs

Given a list of unique words, find all pairs of distinct indices (i, j) in the given list, so that the concatenation of the two words, i.e. words[i] + words[j] is a palindrome.

Example 1:

Given words = ["bat", "tab", "cat"]

Return [[0, 1], [1, 0]]

The palindromes are ["battab", "tabbat"]

Example 2:

Given words = ["abcd", "dcba", "lls", "s", "sssll"]

Return [[0, 1], [1, 0], [3, 2], [2, 4]]

The palindromes are ["dcbaabcd", "abcddcba", "slls", "llssssll"]

题解

通过hash表来来查找字符串对应下标。

对于每个字符串str:

  1. 如果字符串是回文串,那么“”+str和str+“”必定是回文串,只需要从hash表中找“”对应的下标
  2. 把字符串分成两半left和right,记left和right的逆串是left_r和right_r:

    a. 如果left是回文串,right_r+str必定是回文串,只需要从hash表中找right_r对于的下标

    b. 如果right是回文串,str+left_r必定是回文串,只需要从hash表中找left_r对应的下标

对于第2步,我以下的代码是利用Manacher算法求出每个字符对应的最大回文串的半径,通过坐标加减半径是否等于0或strlen(len)来判断left和right是否为回文串。假设有k字符串,每个字符串最大长度是n,一开始我以为利用Manacher算法的时间复杂度应该是O(k*n),但是由于取子串和反转子串的时间复杂度是O(n),利用Manacher算法的最坏时间复杂度还是O(k*n^2)。

LeetCode测试的时候发现,普通比较回文串的方法比用Manacher算法速度要快。对于普通匹配的方法的最快情况对应的也是Manacher的最坏情况,而Manacher会比较复杂一些,时间常数比较大。而在一般情况下,普通匹配在大部分情况下都是第一步匹配就不成功,匹配速度很快,况且LeetCode的数据一般都不大,复杂度不满足都经常AC。

但是,我还是想在练一下Manacher算法啊,为什么?几乎所有回文串问题都可以转化成回文子串问题,而回文子串问题,用Manacher算法一般都可以解决的。

注意:对于“”一定要跳过,因为它是回文串,会匹配自己,而且hash表中必定会找打自己的下标。

vector<int> getSubstringRadius(string s) {
string str = "$#";
for(int i = 0; i != s.size(); ++i) {
str.push_back(s[i]);
str.push_back('#');
}
str.push_back('~');
int id = 0;
int mx = 0;
vector<int> p(str.size());
for (int i = 1; i < p.size() - 1; ++i) {
if (i < mx)
p[i] = p[2 * id - i] < mx - i ? p[2 * id - i] : mx - i;
else
p[i] = 1;
while (str[i + p[i]] == str[i - p[i]]) ++p[i];
if (i + p[i] > mx) {
mx = i + p[i];
id = i;
}
}
return p;
} vector<vector<int>> palindromePairs(vector<string>& words) {
unordered_map<string, int> hash;
for (int i = 0; i != words.size(); ++i) hash[words[i]] = i;
vector<vector<int>> result;
string sub;
for (int i = 0; i != words.size(); ++i) {
if (words[i].size() == 0) continue; //""跳过,因为只能和自己成对
vector<int> radius = getSubstringRadius(words[i]); //Manacher算法得出的数组
//字符串是回文串时,找""
if ((radius.size() / 2- radius[radius.size()/ 2]) / 2 == 0) {
if (hash.find("") != hash.end()) {
result.push_back(vector<int> {i, hash[""]});
result.push_back(vector<int> {hash[""], i});
}
} else {
//不是回文串,找字符串的逆串
sub = words[i];
reverse(sub.begin(), sub.end());
if (hash.find(sub) != hash.end())
result.push_back(vector<int> {i, hash[sub]});
}
//遍历左边的元素,如果左边是回文串
for (int j = 2; j < radius.size() / 2; ++j) {
if ((j - radius[j]) / 2 == 0) {
sub = words[i].substr((j + radius[j]) / 2 - 1, words[i].size() - radius[j] + 1);
reverse(sub.begin(), sub.end());
if (hash.find(sub) != hash.end())
result.push_back(vector<int> {hash[sub], i});
}
}
//遍历右边的元素,如果右边是回文串
for (int j = radius.size() / 2 + 1; j < radius.size() - 2; ++j) {
if ((j + radius[j]) / 2 - 2 == words[i].size() - 1) {
sub = words[i].substr(0, words[i].size() - radius[j] + 1);
reverse(sub.begin(), sub.end());
if (hash.find(sub) != hash.end())
result.push_back(vector<int> {i, hash[sub]});
}
}
}
return result;
}

336-Palindrome Pairs的更多相关文章

  1. LeetCode 336. Palindrome Pairs

    原题链接在这里:https://leetcode.com/problems/palindrome-pairs/ 题目: Given a list of unique words, find all p ...

  2. 336. Palindrome Pairs(can't understand)

    Given a list of unique words, find all pairs of distinct indices (i, j) in the given list, so that t ...

  3. 【LeetCode】336. Palindrome Pairs 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 HashTable 相似题目 参考资料 日期 题目地 ...

  4. leetcode@ [336] Palindrome Pairs (HashMap)

    https://leetcode.com/problems/palindrome-pairs/ Given a list of unique words. Find all pairs of dist ...

  5. 336 Palindrome Pairs 回文对

    给定一组独特的单词, 找出在给定列表中不同 的索引对(i, j),使得关联的两个单词,例如:words[i] + words[j]形成回文.示例 1:给定 words = ["bat&quo ...

  6. 【leetcode】336. Palindrome Pairs

    题目如下: 解题思路:对于任意一个word,要找出在wordlist中是否存在与之能组成回文的其他words,有两种思路.一是遍历wordlist:二是对word本身进行分析,找出能组成回文的word ...

  7. DP VK Cup 2012 Qualification Round D. Palindrome pairs

    题目地址:http://blog.csdn.net/shiyuankongbu/article/details/10004443 /* 题意:在i前面找回文子串,在i后面找回文子串相互配对,问有几对 ...

  8. 【题解】Palindrome pairs [Codeforces159D]

    [题解]Palindrome pairs [Codeforces159D] 传送门:\(Palindrome\) \(pairs\) \([CF159D]\) [题目描述] 给定一个长度为 \(N\) ...

  9. leetcode 132 Palindrome Pairs 2

    lc132 Palindrome Pairs 2 大致与lc131相同,这里要求的是最小分割方案 同样可以分割成子问题 dp[i][j]还是表示s(i~j)是否为palindrome res[i]则用 ...

  10. leetcode 131 Palindrome Pairs

    lc131 Palindrome Pairs 解法1: 递归 观察题目,要求,将原字符串拆成若干子串,且这些子串本身都为Palindrome 那么挑选cut的位置就很有意思,后一次cut可以建立在前一 ...

随机推荐

  1. pyqt5安装

    花了一天时间,终于是装好了. 这东西硬是把我从Python2掰弯成了Python3 本来用pip安装了一个pyqt,但是后来才发现,这是个x64版本的. 我不知道啊! 我以为是还要装qt5 所以我把q ...

  2. ThinkPHP3.2.3 跨域访问

    其他程序调用tp项目的action时需要进行跨域设置,在tp项目根目录下添加crossdomain.xml文件. 文件内容:  <?xml version="1.0"?> ...

  3. java中interface的详解

    JAVA的核心概念:接口(interface) 接口与类属于同一层次,实际上,接口是一种特殊的抽象类. 如:    interface IA{ }  public interface: 公开接口  与 ...

  4. 无需Try catch 的UI事件封装类

    在UI处理中,经常需要进行异常处理,以便在错误发生时能够进行一些自定义的操作,比如,弹出消息框给用户,进行重试操作,记录日志等,如果能够让用户写代码时不用写try...catch,而只是关注业务逻辑的 ...

  5. WebStorm注册码

    WebStorm注册码User Name:EMBRACE License Key:===== LICENSE BEGIN =====24718-1204201000001h6wzKLpfo3gmjJ8 ...

  6. EasyUI DataGrid 分页实现示例

    使用easyui可以很方便的开发web程序,这儿仅展示一个后台使用mvc来实现分页的示例,截图如下 示例代码如下 1. 创建模型类,代码如下 using System; using System.Co ...

  7. ios 使用Core Image实现高斯模糊

    在iOS和OS X平台上,Core Image都提供了大量的滤镜(Filter),这也是Core Image库中比较核心的东西之一.按照官方文档记载,在OS X上有120多种Filter,而在iOS上 ...

  8. CSS鼠标悬停图片加边框效果,不位移的方法

    <!DOCTYPE HTML> <html lang="en-US"> <head> <title>css实现鼠标悬停时图片加边框效 ...

  9. CS 231n----Assignment1 记录

    记录下在完成cs231n的Assignment1过程中的一些东西. 1. scores是一个N*C的array,N是训练样本个数,C是标签.y是(N,)的数组,取出每一个样本对应的score,可以用以 ...

  10. 使用ab进行压力测试

    在Windows系统的命令行下,进入ab.exe程序所在目录,执行ab.exe程序.注意直接双击无法正确运行.