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. [C#对Oracle操作]C#操作调用Orcale存储过程有参数

    /// <summary> /// 获取ERP固定资产计提数据 /// </summary> /// <param name="strCompanyCode&q ...

  2. android中MVP模式

    http://blog.csdn.net/ysh06201418/article/details/46534799 Android App整体架构设计的思考   http://blog.csdn.ne ...

  3. WCF配置

    服务端 <system.serviceModel> <services> <service name="WCF.Homedo.Service.Cache.Ser ...

  4. 安装了多个Oracle11g的客户端,哪个客户端的tnsnames.ora会起作用?

    如果我们由于需要安装了多个Oracle的client,哪个客户端的tnsnames.ora会起作用呢? 答案是: 在安装好clinent端后,安装程序会把client的bin目录放到path里面,pa ...

  5. 学习FFmpeg API

    ffmpeg是编解码的利器,用了很久,以前看过dranger 的教程,非常精彩,受益颇多,是学习ffmpeg api很好的材料.可惜的是其针对的ffmpeg版本已经比较老了,而ffmpeg的更新又很快 ...

  6. 【ios 7】 之后的设置系统的状态栏隐藏的方法分享

    由于在做视频播放的的项目,一直困扰的是,视频全屏幕播放的时候,系统的状态栏会隐藏不掉,虽然可以设置为透明的状态来显示,但是电池的状态一直隐藏不掉,查看网上的说法也就是说,要么来控制,他的hidden ...

  7. 安装spf13-vim on Windows10

    安装之前 1.系统为 windows10  Version 1607 64位 企业版 2.参考 http://www.codeweblog.com/gvim-64%E4%BD%8D-windows-7 ...

  8. vs2010 sql server 2008数据库管理界面安装

    http://jingyan.baidu.com/article/1e5468f928e106484961b7b0.html

  9. 100怎么变成100.00 || undefined在数字环境下是:NaN || null在数字环境下是0 || 数组的toString()方法把每个元素变成字符串,拼在一起以逗号隔开 || 空数组转换成字符串后是什么?

    100怎么变成100.00?

  10. 移动端自动化环境搭建-wxpython的安装

    安装wxpython A.安装依赖 wxPython 是 Python 非常有名的一个 GUI 库,因为 RIDE 是基于这个库开发的,所以这个必须安装. B.安装过程 下载地址:http://www ...