Palindrome Pairs

Palindrome Pairs

Example:

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:

Given words = ["bat", "tab", "cat"]

Return [[0, 1], [1, 0]]

The palindromes are ["battab", "tabbat"]

Example 2:

Given words = ["abcd", "dcba", "lls", "s", "sssll"]

Return [[0, 1], [1, 0], [3, 2], [2, 4]]

The palindromes are ["dcbaabcd", "abcddcba", "slls", "llssssll"]

Algorithm:

1 Since we need return a list of lists, containing indices whose words if we combine shall result in a palindrome, it makes intuitive sense to have a mapping between words in the given array and their corresponding indices. Therefore lets populate a hash map with the words and their indices.

2 For each unique word in the words array, consider the word to be divided into two substrings, str1 and str2, with str1 progressively increasing from "" (empty) substring to the entire word while str2 assumes the remaining part of the word. Check if str1 is a palindrome and if so then there is a possibility of it functioning as the pivot around which a palindrome could be formed. In order to determine whether a palindrome could be indeed formed, determine whether the reverse of the str2 exists within the map and does not correspond to the current index in contention (as is the case in case str2 is "aa" in which case reverse of str2 is also "aa" and hence can correspond to the current index in the map), so as to function as a prefix to form a palindrome with str1 as the pivot.

3 If the reversed string is indeed present in the map and does not correspond to the current index, then you have got one pair of palindromes that can be added to the result list of lists. Create a temporary list, and add the prefix reversed string's index to the temp list first, followed by current index i and add the temp list to the resultant list of lists.

4 Now like wise check if str2 is a palindrome, in which case it can function as a pivot around which a palindrome can be formed. Check if the str1's reverse is present in the map and does not correspond to the current index. Also in order to consider the corner case of "" empty string being one of the words in the array, there is a need to iterate until the length of word[i] inclusive. But this may lead to empty string "" being considered in str2 as a duplicate in addition to being considered initially in str1. Therefore care must be taken to ensure that str2 is not equal to empty string to avoid duplicates. If all the above checks are satisfied, then create a temp list, add the prefix index i and the suffix index from the map corresponding to the reversed str1, and add the temp list to result list of lists. After iterating through the entire words list, return the result list of lists.

Test:

1 Test with empty words in the words array.

2 Test with no palindrome pairs.

3 Test with words containing the same letter but increasing length like ["a", "aa"]

Solution:

class Solution {
    public List<List<Integer>> palindromePairs(String[] words) {
    //result list of lists
    List<List<Integer>> res = new ArrayList<>();

    if(words == null || words.length < 2) 
        return res;

    //declare hashmap
    HashMap<String, Integer> map = new HashMap<>();

    
    //map each word and its index in hashmap
    for (int i = 0; i < words.length; i++) {
        map.put(words[i], i); 
    }

    //iterate over words array
    for (int i = 0; i < words.length; i++) {
       //iterate over each letter in each word; <= to take into account "" word
    for (int j = 0; j <= words[i].length(); j++) {
            //substring 1
            String str1 = words[i].substring(0, j);
            //substring 2; remaining part of the words[i]
            String str2 = words[i].substring(j);

            if (isPalindrome(str1)) {
              
                String str2revs = new StringBuilder(str2).reverse().toString();
                if (map.containsKey(str2revs) && map.get(str2revs) != i) {
                    List<Integer> temp = new ArrayList<>();
                    temp.add(map.get(str2revs));
                    temp.add(i);
                    res.add(temp);
                 } 
            }

            if (isPalindrome(str2)) {
               String str1revs = new StringBuilder(str1).reverse().toString();
               if (map.containsKey(str1revs) && map.get(str1revs) != i && str2.length() != 0) {
                   List<Integer> temp = new ArrayList<>();
                   temp.add(i);
                   temp.add(map.get(str1revs));
                   res.add(temp);
               } 
            }
        }
    }
    return res;

    // T O(nk^2) n length of words, 
//k avg/worst case length of each word S O(n)
//k^2 coz of substring and reverse both costs k each 
}

private boolean isPalindrome (String word) {

int left = 0;
int right = word.length() - 1;
while(left <= right) {
if(word.charAt(left++) != word.charAt(right--)) return false;
}
return true;
}

}

//https://gist.github.com/harycane/edd627614dfa4d2b369001b41f48bd4c

Complexity Analysis:

Assuming size of words array is n and each word in the worst case has a length of k, then iterating through each word to form the substrings and reversing each word incurs cost of k therefore in total k^2. In addition since we iterate through the words array an additional factor of n is incurred. So in total time complexity incurred is T O(nk^2). Space complexity is S O(n), for we map the size of words array onto the hash map.

要查看或添加评论,请登录

Hary Krishnan的更多文章

  • Missing Number

    Missing Number

    Given an array nums containing n distinct numbers in the range [0, n], return the only number in the range that is…

  • Reorder data in log files

    Reorder data in log files

    https://leetcode.com/problems/reorder-data-in-log-files/description/ You have a list of logs.

    1 条评论
  • Shortest Distance

    Shortest Distance

    https://leetcode.com/problems/shortest-word-distance/ Given a list of words and two words word1 and word2, return the…

  • Shortest Distance II

    Shortest Distance II

    https://leetcode.com/problems/shortest-word-distance-ii/description/ https://gist.

  • Nested List Weight Sum I & II

    Nested List Weight Sum I & II

    https://leetcode.com/problems/nested-list-weight-sum/description/ https://leetcode.

  • Sliding Window Maximum

    Sliding Window Maximum

    Given an array nums, there is a sliding window of size k which is moving from the very left of the array to the very…

  • Permutations

    Permutations

    Given a collection of distinct integers, return all possible permutations. Example: Input: [1,2,3] Output: [ [1,2,3],…

  • Gas Station

    Gas Station

    Example: There are N gas stations along a circular route, where the amount of gas at station i is gas[i]. You have a…

  • Group Anagrams

    Group Anagrams

    Example: Given an array of strings, group anagrams together. Example: Input: ["eat", "tea", "tan", "ate", "nat"…

    1 条评论
  • First Duplicate

    First Duplicate

    Example: Given an array a that contains only numbers in the range from 1 to a.length, find the first duplicate number…

社区洞察

其他会员也浏览了