回文对
记录我的刷题
给定一组唯一的单词, 找出所有不同 的索引对(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”]
public class palindromePairs {
/**
* 力扣 暴力解法
* 时间复杂度O(n^2 * k) , n 指的是单词的数量,k 指的是最长单词的长度。
* @param words
* @return
*/
public static List<List<Integer>> palindromePairsOne(String[] words) {
List<List<Integer>> pairs = new ArrayList<>();
for (int i = 0; i < words.length; i++) {
for (int j = 0; j < words.length; j++) {
if (i == j) {
continue;
}
//两个字符串组合
String combined = words[i].concat(words[j]);
//反转
String reversed = new StringBuilder(combined).reverse().toString();
//比较 相等加入链表
if (combined.equals(reversed)) {
pairs.add(Arrays.asList(i, j));
}
}
}
return pairs;
}
/**
*散列解法
*/
public static List<List<Integer>> palindromePairsTwo(String[] words){
List<List<Integer>> pairs = new ArrayList<>();
HashMap<String,Integer> hashMap = new HashMap<>();
//存入哈希表
for(int i=0;i<words.length;i++){
hashMap.put(words[i],i);
}
for(int i=0;i<words.length;i++){
//第一种情况,字符串长度相等
String reversed = new StringBuilder(words[i]).reverse().toString();
if(hashMap.containsKey(reversed)){
if(hashMap.get(reversed) != i){
pairs.add(Arrays.asList(i,hashMap.get(reversed)));
}
}
for(int j=0;j<words[i].length();j++){
//求有效后缀,即前缀为回文,后缀为非回文,判断是否存在 后缀取反
if(isParmlind(words[i],0,j)){
//截取后缀,并取反
String wordReversedSuffixes = new StringBuilder(words[i].substring(j+1)).reverse().toString();
//判断是否存在 后缀取反
if(hashMap.containsKey(wordReversedSuffixes)){
//不与当前数组序号相等,则证明不是同一个字符,然后加入列表
if(hashMap.get(wordReversedSuffixes) != i) {
pairs.add(Arrays.asList(hashMap.get(wordReversedSuffixes),i));
}
}
}
//有效前缀,即前缀非回文,后缀为回文,判断是否存在 前缀取反
if(isParmlind(words[i],j,words[i].length()-1)){
String wordReversedPrefixes = new StringBuilder(words[i].substring(0,j)).reverse().toString();
if(hashMap.containsKey(wordReversedPrefixes)){
if(hashMap.get(wordReversedPrefixes)!=i) {
pairs.add(Arrays.asList(i,hashMap.get(wordReversedPrefixes)));
}
}
}
}
}
return pairs;
}
//求是否为回文字符
public static boolean isParmlind(String s, int left, int right) {
while(left < right) {
if(s.charAt(left) != s.charAt(right)) {
return false;
}
left++;
right--;
}
return true;
}
public static void main(String[] args) {
String[] arr = {"abcd","dcba","lls","s","sssll"};
System.out.println("方法一:");
for(List<Integer> list : palindromePairsOne(arr)){
System.out.println(list);
}
System.out.println("方法二:");
for(List<Integer> list : palindromePairsTwo(arr)){
System.out.println(list);
}
}
}