[LeetCode] 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:

Input: ["abcd","dcba","lls","s","sssll"]
Output: [[0,1],[1,0],[3,2],[2,4]] 
Explanation: The palindromes are ["dcbaabcd","abcddcba","slls","llssssll"]

Example 2:

Input: ["bat","tab","cat"]
Output: [[0,1],[1,0]] 
Explanation: The palindromes are ["battab","tabbat"]

回文对。题意是给一组不重复的单词,找出所有可以组成回文的单词对。

这里我给出比较通俗的解法。创建一个isPalindrome的函数帮助判断是否是回文,同时创建一个hashmap记录每个单词和他们各自的index。遍历input中的每个单词,并且按字符一位一位地将单词断开,看单词的左半边是否是回文。若是,则在hashmap中找是否有这个回文半边的另一半,若有则加入结果集。

跑一个例子说明吧。比如第一个例子中的"sssll",判断的时候,会发现ss是回文(当然,之前的s也是回文),所以需要去找sll的reverse -> lls是否存在于hashmap,发现存在,则把两者的index [2, 4]加入结果集。

时间O(n * k^2) - n个单词,K是单词的长度

空间O(n) - hashmap

Java实现

 1 class Solution {
 2     public List<List<Integer>> palindromePairs(String[] words) {
 3         List<List<Integer>> res = new ArrayList<>();
 4         // corner case
 5         if (words == null || words.length < 2) {
 6             return res;
 7         }
 8 
 9         // normal case
10         HashMap<String, Integer> map = new HashMap<>();
11         for (int i = 0; i < words.length; i++) {
12             map.put(words[i], i);
13         }
14 
15         for (int i = 0; i < words.length; i++) {
16             for (int j = 0; j <= words[i].length(); j++) {
17                 String str1 = words[i].substring(0, j);
18                 String str2 = words[i].substring(j);
19                 if (isPalindrome(str1)) {
20                     String str2rvs = new StringBuilder(str2).reverse().toString();
21                     if (map.containsKey(str2rvs) && map.get(str2rvs) != i) {
22                         res.add(Arrays.asList(map.get(str2rvs), i));
23                     }
24                 }
25                 if (str2.length() != 0 && isPalindrome(str2)) {
26                     String str1rvs = new StringBuilder(str1).reverse().toString();
27                     if (map.containsKey(str1rvs) && map.get(str1rvs) != i) {
28                         res.add(Arrays.asList(i, map.get(str1rvs)));
29                     }
30                 }
31             }
32         }
33         return res;
34     }
35 
36     private boolean isPalindrome(String s) {
37         int left = 0;
38         int right = s.length() - 1;
39         while (left <= right) {
40             if (s.charAt(left) != s.charAt(right)) {
41                 return false;
42             }
43             left++;
44             right--;
45         }
46         return true;
47     }
48 }

 

JavaScript实现

 1 /**
 2  * @param {string[]} words
 3  * @return {number[][]}
 4  */
 5 var palindromePairs = function (words) {
 6     const map = words.reduce((acc, cur, i) => {
 7         acc[cur] = i;
 8         return acc;
 9     }, {});
10     const output = [];
11     for (const word of words) {
12         for (let j = 0; j <= word.length; j++) {
13             if (j < word.length && isPalindrome(word, j, word.length)) {
14                 const rLeft = reverseSubstring(word, 0, j);
15                 if (rLeft in map) {
16                     output.push([map[word], map[rLeft]]);
17                 }
18             }
19             if (isPalindrome(word, 0, word.length - j)) {
20                 const rRight = reverseSubstring(
21                     word,
22                     word.length - j,
23                     word.length
24                 );
25                 if (rRight in map && rRight !== word) {
26                     output.push([map[rRight], map[word]]);
27                 }
28             }
29         }
30     }
31     return output;
32 };
33 
34 function reverseSubstring(word, start, end) {
35     let output = '';
36     for (let i = end - 1; i >= start; i--) {
37         output += word[i];
38     }
39     return output;
40 }
41 
42 function isPalindrome(word, start, end) {
43     let left = start;
44     let right = end - 1;
45     while (left < right) {
46         if (word[left] !== word[right]) {
47             return false;
48         }
49         left += 1;
50         right -= 1;
51     }
52     return true;
53 }

 

LeetCode 题目总结

posted @ 2020-04-10 06:43  CNoodle  阅读(163)  评论(0编辑  收藏  举报