今天遇到算法bug,查错用了好久。添加链接描述
给定一组 互不相同 的单词, 找出所有不同 的索引对(i, j),使得列表中的两个单词, words[i] + words[j] ,可拼接成回文串。
示例 1:
输入:["abcd","dcba","lls","s","sssll"]
输出:[[0,1],[1,0],[3,2],[2,4]]
解释:可拼接成的回文串为 ["dcbaabcd","abcddcba","slls","llssssll"]
示例 2:
输入:["bat","tab","cat"]
输出:[[0,1],[1,0]]
解释:可拼接成的回文串为 ["battab","tabbat"]
看了题目之后,我没有一点头绪,不想用暴力解法,直接看了题解,确实不好想。
逻辑是一个字符串,拆成两部分,其中一部分是回文串,另一部分,反向字符串存在数组中,即满足题目条件
以“sssll”来举例说明
sssll 拆分成 s + ssll
s是回文串,若数组中存在 ssll的反向串,即llss,那就满足条件 即 llss + sssll 就是回文
ssll不是回文串,舍弃。
sssll 拆分成 ss + sll
ss是回文串,若数组中存在 sll的反向串,即lls,那就满足条件 即 lls + sssll 就是回文
sll不是回文串,舍弃。
以此类推
sssll 拆分成 sss + ll
sss是回文串,若数组中存在 ll的反向串,即ll,那就满足条件 即 ll + sssll 就是回文
ll是回文串,若数组中存在 sss的反向串,即sss,就满足条件 sssll + sss 就是回文
上代码
public List<List<Integer>> palindromePairs(String[] words) {
// 反向单词放到 哈希表中
Map<String,Integer> map = new HashMap<>();
int len = words.length;
for(int i = 0; i < len; i++){
String re_item = new StringBuilder(words[i]).reverse().toString();
map.put(re_item, i);
}
List<List<Integer>> res = new ArrayList<>();
// 边界有回文,剩余部分,以反向表中存在,那就有结果
for(int i = 0; i < len; i++){
String word = words[i];
int n = word.length();
if(n == 0) continue;
for(int j = -1; j < n; j++){
//左边界至j 是回文
if(isPalindrome(word, 0, j)){
String sub = word.substring(j + 1);
int subIndex = hasReverse(map, sub);
if(subIndex != -1 && subIndex != i){
res.add(Arrays.asList(subIndex,i));
}
}
// 右边界至j 是回文
if(isPalindrome(word, j + 1, n -1)){
String sub = word.substring(0, j + 1);
int subIndex = hasReverse(map, sub);
if(subIndex != -1 && subIndex != i){
res.add(Arrays.asList(i,subIndex));
}
}
}
}
return res.stream().distinct().collect(Collectors.toList());
}
/*
*数组中是否含有反向串
*/
private int hasReverse(Map<String,Integer> map, String item){
return map.getOrDefault(item, -1);
}
/*
* 是不是回文串
*/
private boolean isPalindrome (String word, int left, int right){
while(left < right){
if(word.charAt(left++) != word.charAt(right--)){
return false;
}
}
return true;
}
我遇到的bug是[“a”,""],这种情况下,正确结果应该是 [0,1] 和[1,0] ,但是我原来的代码只能出来一个,另外一个出不来。
原代码 for(int j = 0; j < n; j++)
修改为 for(int j = -1; j < n; j++)
引入的问题,是结果重复。
原代码 return res;
修改为 return res.stream().distinct().collect(Collectors.toList());
结果算是通过了,准备睡觉,不再优化。其实可以优化到不产生重复结果的,没心电去扣细节了。