【LeetCode】336. Palindrome Pairs 迴文對(Hard)(JAVA)
阿新 • • 發佈:2020-12-19
技術標籤:Leetcode字串leetcodejava面試資料結構
【LeetCode】336. Palindrome Pairs 迴文對(Hard)(JAVA)
題目地址: https://leetcode.com/problems/palindrome-pairs/
題目描述:
Given a list of unique words, return all the pairs of thedistinct indices (i, j) in the given list, so that the concatenation of the two wordswords[i] + words[j] is a palindrome.
Example 1:
Input: words = ["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: words = ["bat","tab","cat"] Output: [[0,1],[1,0]] Explanation: The palindromes are ["battab","tabbat"]
Example 3:
Input: words = ["a",""]
Output: [[0,1],[1,0]]
Constraints:
- 1 <= words.length <= 5000
- 0 <= words[i].length <= 300
- words[i] consists of lower-case English letters.
題目大意
給定一組 互不相同 的單詞, 找出所有不同 的索引對(i, j),使得列表中的兩個單詞, words[i] + words[j] ,可拼接成迴文串。
解題方法
暴力求解
- 直接暴力判斷每兩個字串是否是迴文數
- 時間複雜度: O(n^2)
class Solution {
public List<List<Integer>> palindromePairs(String[] words) {
List<List<Integer>> list = new ArrayList<>();
for (int i = 0; i < words.length; i++) {
for (int j = i + 1; j < words.length; j++) {
if (isPal(words[i] + words[j])) {
List<Integer> temp = new ArrayList<>();
temp.add(i);
temp.add(j);
list.add(temp);
}
if (isPal(words[j] + words[i])) {
List<Integer> temp = new ArrayList<>();
temp.add(j);
temp.add(i);
list.add(temp);
}
}
}
return list;
}
public boolean isPal(String str) {
int start = 0;
int end = str.length() - 1;
while (start < end) {
if (str.charAt(start) != str.charAt(end)) return false;
start++;
end--;
}
return true;
}
}
超時: Time Limit Exceeded
優化
- 把每個 string 和對應的 index 用 map 的形式存起來
- 判斷 string 的 [0, k] 部分是否是迴文數,如果是迴文數,[k + 1, len - 1] 逆轉為 rev 拼接到 string 前面也是一個迴文數,所以如果 rev 在 map 裡面, rev + string 就可以組成迴文數
class Solution {
public List<List<Integer>> palindromePairs(String[] words) {
Map<String, Integer> map = new HashMap<>();
List<List<Integer>> list = new ArrayList<>();
for (int i = 0; i < words.length; i++) {
map.put(words[i], i);
}
for (int i = 0; i < words.length; i++) {
String reverse = reverse(words[i]);
Integer temp = map.get(reverse);
if (temp != null && temp != i) {
List<Integer> cur = new ArrayList<>();
cur.add(i);
cur.add(temp);
list.add(cur);
}
for (int j = 1; j <= words[i].length(); j++) {
if (isPal(words[i], 0, j - 1)) {
String curRev = reverse.substring(0, words[i].length() - j);
temp = map.get(curRev);
if (temp != null) {
List<Integer> cur = new ArrayList<>();
cur.add(temp);
cur.add(i);
list.add(cur);
}
}
if (isPal(words[i], words[i].length() - j, words[i].length() - 1)) {
String curRev = reverse.substring(j);
temp = map.get(curRev);
if (temp != null) {
List<Integer> cur = new ArrayList<>();
cur.add(i);
cur.add(temp);
list.add(cur);
}
}
}
}
return list;
}
public String reverse(String str) {
return new StringBuilder(str).reverse().toString();
}
public boolean isPal(String str, int start, int end) {
while (start < end) {
if (str.charAt(start) != str.charAt(end)) return false;
start++;
end--;
}
return true;
}
}
執行耗時:51 ms,擊敗了87.94% 的Java使用者
記憶體消耗:40 MB,擊敗了97.17% 的Java使用者