Count Prefix and Suffix Pairs II - Complete Solution Guide
Count Prefix and Suffix Pairs II is LeetCode problem 3045, a Hard level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.
Problem Statement
You are given a 0-indexed string array words . Let's define a boolean function isPrefixAndSuffix that takes two strings, str1 and str2 : isPrefixAndSuffix(str1, str2) returns true if str1 is both a prefix and a suffix of str2 , and false otherwise. For example, isPrefixAndSuffix("aba", "ababa") is true because "aba" is a prefix of "ababa" and also a suffix, but isPrefixAndSuffix("abc", "abcd") is false . Return an integer denoting the number of index pairs (i , j) such that i < j , and isPrefixA
Detailed Explanation
The problem asks us to count the number of pairs of strings (words[i], words[j]) in a given array of strings 'words', where i < j, and 'words[i]' is both a prefix and a suffix of 'words[j]'. A prefix of a string is a substring that starts at the beginning of the string, and a suffix is a substring that ends at the end of the string. We need to find all pairs (i, j) satisfying i < j such that words[i] is both a prefix and a suffix of words[j], and return the total count of such pairs.
Solution Approach
The provided solution uses a rolling hash technique with two different prime numbers to efficiently determine if one string is both a prefix and a suffix of another. For each word in the input array, the solution calculates prefix hashes and powers of the prime base. Then, for each possible length 'l' from 1 to the length of the current word, the solution calculates the hash of the prefix and the hash of the suffix of length 'l'. If these hashes match for both prime bases, it implies that the prefix and suffix are equal. A hash map is used to keep track of how many times each word has occurred, which helps to count the pairs efficiently. The solution avoids string comparisons and uses efficient hashing for comparing substrings.
Step-by-Step Algorithm
- Step 1: Initialize two prime numbers (P1, P2) and two modulo values (M1, M2) for hashing. Initialize a hash map 'counts' to store the frequency of each word (represented by its hash values) and a variable 'ans' to store the final count of pairs.
- Step 2: Iterate through each 'word' in the input 'words' array.
- Step 3: Calculate prefix hashes (h1_pref, h2_pref) and powers of prime bases (p1_powers, p2_powers) for the current 'word'.
- Step 4: Iterate through all possible lengths 'l' from 1 to the length of the 'word'.
- Step 5: Calculate the hash of the prefix of length 'l' (h1_p, h2_p) and the hash of the suffix of length 'l' (h1_s, h2_s).
- Step 6: If h1_p == h1_s and h2_p == h2_s, it means that the prefix and suffix of length 'l' are equal. Increment 'ans' by the number of times the string represented by the hash values (h1_p, h2_p) has appeared previously (using the 'counts' hash map).
- Step 7: After iterating through all possible lengths 'l', store the frequency of the current 'word' (represented by its hash values (h1_pref[L], h2_pref[L])) in the 'counts' hash map.
- Step 8: After iterating through all 'words', return the final count 'ans'.
Key Insights
- Insight 1: Using brute-force string comparison for each pair of words would be inefficient, especially with the given constraints (up to 10^5 words, up to 10^5 length per word).
- Insight 2: Rolling hash is an efficient method for determining if two substrings are equal by comparing their hash values instead of directly comparing the strings. Using two different prime numbers for the hashing helps in avoiding collision issues.
- Insight 3: Pre-computing the powers of the prime base and the prefix hashes allows for efficient calculation of suffix hashes.
Complexity Analysis
Time Complexity: O(n*m^2)
Space Complexity: O(n)
Topics
This problem involves: Array, String, Trie, Rolling Hash, String Matching, Hash Function.
Companies
Asked at: Autodesk, Capital One, Samsung.