1. 程式人生 > 其它 >【LeetCode】336. Palindrome Pairs 迴文對(Hard)(JAVA)

【LeetCode】336. Palindrome Pairs 迴文對(Hard)(JAVA)

技術標籤: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] ,可拼接成迴文串。

解題方法

暴力求解

  1. 直接暴力判斷每兩個字串是否是迴文數
  2. 時間複雜度: 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

優化

  1. 把每個 string 和對應的 index 用 map 的形式存起來
  2. 判斷 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使用者

歡迎關注我的公眾號,LeetCode 每日一題更新