题目描述
给定一组 互不相同 的单词, 找出所有 不同 的索引对 (i, j),使得列表中的两个单词, words[i] + words[j] ,可拼接成回文串。
示例 1:
输入:words = [“abcd”,“dcba”,“lls”,“s”,“sssll”]
输出:[[0,1],[1,0],[3,2],[2,4]]
解释:可拼接成的回文串为 [“dcbaabcd”,“abcddcba”,“slls”,“llssssll”]
示例 2:
输入:words = [“bat”,“tab”,“cat”]
输出:[[0,1],[1,0]]
解释:可拼接成的回文串为 [“battab”,“tabbat”]
示例 3:
输入:words = [“a”,""]
输出:[[0,1],[1,0]]
提示:
- 1 <= words.length <= 5000
- 0 <= words[i].length <= 300
- words[i] 由小写英文字母组成
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/palindrome-pairs
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
若两个字符s1、s2串拼起来是回文串,那就有三种情况:
- s1和s2长度相等,则一个是另一个的翻转
- s1比s2长,那么s1一定可以分割成两部分sub1和sub2,sub1为s2的翻转,sub2是个回文串
- s1比s2短,则相反
算法步骤:
- 将数组中所有字符串翻转,并将对应的下标索引记录下来
- 遍历原字符串数组,判断每个字符的前缀和后缀是否是回文串,若是则找另一部分在翻转字符中是否存在,若存在则找到一组
- 找到一组符合条件时,若前缀是回文串,则反转字符id应放在前缀前面
class Solution {
List<String> reversed = new ArrayList<>();
Map<String,Integer> map = new HashMap<>();
public List<List<Integer>> palindromePairs(String[] words) {
int m = words.length;
for(int i = 0;i < m;++i){
reversed.add(new StringBuilder(words[i]).reverse().toString());
}
for(int j = 0;j < m;++j){
map.put(reversed.get(j),j);
}
List<List<Integer>> res = new ArrayList<>();
for(int i = 0;i < m;++i){
String word = words[i];
int len = word.length();
if(len == 0)
continue;
for(int j = 0;j <= len;++j){
if(j != 0 && isPalind(word,0,j-1)){
int id = map.getOrDefault(word.substring(j,len),-1);
if(id != -1 && id != i){
res.add(Arrays.asList(id,i));
}
}
if(isPalind(word,j,len-1)){
int id = map.getOrDefault(word.substring(0,j),-1);
if(id != -1 && id != i){
res.add(Arrays.asList(i,id));
}
}
}
}
return res;
}
public boolean isPalind(String word,int left,int right){
int n = right-left+1;
for(int i = 0;i < n/2;i++){
if(word.charAt(left+i) != word.charAt(right-i)){
return false;
}
}
return true;
}
}