• [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 题目总结

  • 相关阅读:
    操作系统01_进程和线程管理
    数据库02_字段类型
    鲁滨逊漂流记游戏
    查找数N二进制中1的个数(JS版 和 Java版)
    js中的call、apply
    jQuery对象与Dom对象的相互转换
    jndi配置数据源
    关于JS中变量的作用域-实例
    重写equals()方法时,需要同时重写hashCode()方法
    String与StringBuilder
  • 原文地址:https://www.cnblogs.com/cnoodle/p/12670961.html
Copyright © 2020-2023  润新知