LeetCode //C - 336. Palindrome Pairs

打印 上一主题 下一主题

主题 660|帖子 660|积分 1980

336. Palindrome Pairs

You are given a 0-indexed array of unique strings words.
A palindrome pair is a pair of integers (i, j) such that:


  • 0 <= i, j < words.length,
  • i != j, and
  • words + words[j] (the concatenation of the two strings) is a palindrome
Return an array of all the palindrome pairs of words.
You must write an algorithm with O(sum of words.length) runtime complexity.
 
Example 1:

   Input: words = [“abcd”,“dcba”,“lls”,“s”,“sssll”]
Output: [[0,1],[1,0],[3,2],[2,4]]
Explanation: The palindromes are [“abcddcba”,“dcbaabcd”,“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]]
Explanation: The palindromes are [“a”,“a”]
  Constraints:



  • 1 <= words.length <= 5000
  • 0 <= words.length <= 300
  • words consists of lowercase English letters.
From: LeetCode
Link: 336. Palindrome Pairs

Solution:

Ideas:

1. Reversing and Hashing:


  • The main idea is to use a hash map (or hash table) to store the reversed versions of each word. This allows us to quickly check if there is a word in the array that, when concatenated with another word, forms a palindrome.
2. Palindrome Checks:


  • For each word, the code checks if any prefix or suffix forms a palindrome. If a suffix is a palindrome, it checks if the reverse of the prefix exists in the hash map. If a prefix is a palindrome, it checks if the reverse of the suffix exists in the hash map.
  • By checking both the prefix and suffix, the code can detect potential palindrome pairs that can be formed by concatenating two different words in different orders.
3. Efficient String Handling:


  • The code carefully manages memory, ensuring that strings are duplicated when stored in the hash map. This avoids issues with accessing freed memory, which was a problem in earlier versions of the code.
4. Use of a Hash Map:


  • The hash map is used to store the reversed words along with their indices. This allows for O(1) average-time complexity lookups, which is crucial for achieving the required efficiency given the constraints.
Code:

  1. typedef struct {
  2.     char* word;
  3.     int index;
  4. } HashItem;
  5. typedef struct {
  6.     HashItem* items;
  7.     int size;
  8. } HashMap;
  9. int hashFunc(char* str, int size) {
  10.     unsigned long hash = 5381;
  11.     int c;
  12.     while ((c = *str++)) {
  13.         hash = ((hash << 5) + hash) + c;
  14.     }
  15.     return hash % size;
  16. }
  17. HashMap* createHashMap(int size) {
  18.     HashMap* map = (HashMap*)malloc(sizeof(HashMap));
  19.     map->items = (HashItem*)calloc(size, sizeof(HashItem));
  20.     map->size = size;
  21.     return map;
  22. }
  23. void insertHashMap(HashMap* map, char* word, int index) {
  24.     int hash = hashFunc(word, map->size);
  25.     while (map->items[hash].word != NULL) {
  26.         hash = (hash + 1) % map->size;
  27.     }
  28.     map->items[hash].word = strdup(word);  // Duplicate the word to avoid premature freeing
  29.     map->items[hash].index = index;
  30. }
  31. int searchHashMap(HashMap* map, char* word) {
  32.     int hash = hashFunc(word, map->size);
  33.     while (map->items[hash].word != NULL) {
  34.         if (strcmp(map->items[hash].word, word) == 0) {
  35.             return map->items[hash].index;
  36.         }
  37.         hash = (hash + 1) % map->size;
  38.     }
  39.     return -1;
  40. }
  41. bool isPalindrome(char* word, int left, int right) {
  42.     while (left < right) {
  43.         if (word[left++] != word[right--]) {
  44.             return false;
  45.         }
  46.     }
  47.     return true;
  48. }
  49. char* reverseString(char* word) {
  50.     int len = strlen(word);
  51.     char* reversed = (char*)malloc((len + 1) * sizeof(char));
  52.     for (int i = 0; i < len; i++) {
  53.         reversed[i] = word[len - i - 1];
  54.     }
  55.     reversed[len] = '\0';
  56.     return reversed;
  57. }
  58. int** palindromePairs(char** words, int wordsSize, int* returnSize, int** returnColumnSizes) {
  59.     *returnSize = 0;
  60.     int capacity = 10;
  61.     int** result = (int**)malloc(capacity * sizeof(int*));
  62.     *returnColumnSizes = (int*)malloc(capacity * sizeof(int));
  63.     // Hash map to store reversed words and their indices
  64.     int hashSize = 50000;  // Increased size to reduce collisions
  65.     HashMap* hashMap = createHashMap(hashSize);
  66.     // Insert reversed words into the hash map
  67.     for (int i = 0; i < wordsSize; i++) {
  68.         char* reversed = reverseString(words[i]);
  69.         insertHashMap(hashMap, reversed, i);
  70.         free(reversed);  // Free the reversed string after storing in the hash map
  71.     }
  72.     for (int i = 0; i < wordsSize; i++) {
  73.         int len = strlen(words[i]);
  74.         for (int j = 0; j <= len; j++) {
  75.             // Check if the suffix forms a palindrome and if the reverse of the prefix exists in the map
  76.             if (isPalindrome(words[i], j, len - 1)) {
  77.                 char* prefix = strndup(words[i], j);
  78.                 int index = searchHashMap(hashMap, prefix);
  79.                 if (index != -1 && index != i) {
  80.                     if (*returnSize == capacity) {
  81.                         capacity *= 2;
  82.                         result = (int**)realloc(result, capacity * sizeof(int*));
  83.                         *returnColumnSizes = (int*)realloc(*returnColumnSizes, capacity * sizeof(int));
  84.                     }
  85.                     result[*returnSize] = (int*)malloc(2 * sizeof(int));
  86.                     result[*returnSize][0] = i;
  87.                     result[*returnSize][1] = index;
  88.                     (*returnColumnSizes)[*returnSize] = 2;
  89.                     (*returnSize)++;
  90.                 }
  91.                 free(prefix);  // Safe to free the prefix here
  92.             }
  93.             // Check if the prefix forms a palindrome and if the reverse of the suffix exists in the map
  94.             if (j > 0 && isPalindrome(words[i], 0, j - 1)) {
  95.                 char* suffix = strdup(words[i] + j);
  96.                 int index = searchHashMap(hashMap, suffix);
  97.                 if (index != -1 && index != i) {
  98.                     if (*returnSize == capacity) {
  99.                         capacity *= 2;
  100.                         result = (int**)realloc(result, capacity * sizeof(int*));
  101.                         *returnColumnSizes = (int*)realloc(*returnColumnSizes, capacity * sizeof(int));
  102.                     }
  103.                     result[*returnSize] = (int*)malloc(2 * sizeof(int));
  104.                     result[*returnSize][0] = index;
  105.                     result[*returnSize][1] = i;
  106.                     (*returnColumnSizes)[*returnSize] = 2;
  107.                     (*returnSize)++;
  108.                 }
  109.                 free(suffix);  // Safe to free the suffix here
  110.             }
  111.         }
  112.     }
  113.     // Free the hash table and the words stored in it
  114.     for (int i = 0; i < hashSize; i++) {
  115.         if (hashMap->items[i].word != NULL) {
  116.             free(hashMap->items[i].word);  // Free each stored word
  117.         }
  118.     }
  119.     free(hashMap->items);
  120.     free(hashMap);
  121.     return result;
  122. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

水军大提督

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表