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. <2016-2-2 总结>

    真正的伟人直率真诚,真正的贤人虚怀若谷,真正的强者温文尔雅,有足够的幽默感,尽可能的庄重而不盛气凌人! 真正的伟人直率真诚,真正的贤人虚怀若谷,真正的强者温文尔雅,有足够的幽默感,尽可能的庄重而不盛气 ...

  2. Rhino+envjs-1.2.js 在java运行网站js 工具类

    java爬虫遇到个页面加密的东西,找了些资料学习学习 做了个java运行js的工具类,希望对大家有用,其中用到client(获取js)可以自行换成自己的client.主要是用了 Rhino就是Java ...

  3. 获取Finacial dimension value的description 值

    public static Description findDimensionValueDescription(DimensionValue _dimensionValue, Name _dimens ...

  4. WORD的公式无法与文字对齐

    在使用Mathtype编辑公式后,经常出现以下公式与文字无法对齐的问题: 可以使用以下方式来解决:

  5. mvc4 发布,遇到 403.14 问题,并且iis提示打开目录浏览。。。解决办法

    经测试,只需要在web.config的system.web的同级节点,添加如下代码,即可完美运行.原理参考文章:一.<validation validateIntegratedModeConfi ...

  6. .net MVC3 页面和 action 传值问题

    一.ViewData ViewData ViewBag 的特点和使用场景比较 1.  TempData:类型是字典的键值对结构 特点:值只能取一次.保存在Session中,Controller每次执行 ...

  7. zookeeper是什么?原理是什么?【转】

    ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,它包含一个简单的原语集,分布式应用程序可以基于它实现同步服务,配置维护和命名服务等.Zookeeper是hadoop的一个子项目,其 ...

  8. JS-安全检测JavaScript基本数据类型和内置对象的方法

    前言:在前端开发中经常会需要用到检测变量数据类型的需求,比如:判断一个变量是否为undefined或者null来进行下一步的操作,今天在阅读“编写高质量代码-改善JavaScript程序的188个建议 ...

  9. 20条Linux命令面试问答

    程序师  http://www.techug.com/20-linux-command-interview-questions 问:1 如何查看当前的Linux服务器的运行级别? 答: ‘who -r ...

  10. mac boot2docker certs not valid with 1.7

    摘自:https://github.com/boot2docker/boot2docker/issues/824 An error occurred trying to connect: Get ht ...