Problem 3043 Find the Length of the Longest Common Prefix
Table of Contents
Problem Statement
Link - Problem 3043
Question
You are given two arrays with positive integers arr1
and arr2
.
A prefix of a positive integer is an integer formed by one or more of its digits, starting from its leftmost digit. For example, 123
is a prefix of the integer 12345
, while 234
is not.
A common prefix of two integers a
and b
is an integer c
, such that c
is a prefix of both a
and b
. For example, 5655359
and 56554
have common prefixes 565
and 5655
while 1223
and 43456
do not have a common prefix.
You need to find the length of the longest common prefix between all pairs of integers (x, y)
such that x
belongs to arr1
and y
belongs to arr2
.
Return the length of the longest common prefix among all pairs. If no common prefix exists among them, return 0
.
Example 1:
Input: arr1 = [1,10,100], arr2 = [1000] Output: 3 Explanation: There are 3 pairs (arr1[i], arr2[j]): - The longest common prefix of (1, 1000) is 1. - The longest common prefix of (10, 1000) is 10. - The longest common prefix of (100, 1000) is 100. The longest common prefix is 100 with a length of 3.
Example 2:
Input: arr1 = [1,2,3], arr2 = [4,4,4] Output: 0 Explanation: There exists no common prefix for any pair (arr1[i], arr2[j]), hence we return 0. Note that common prefixes between elements of the same array do not count.
Constraints:
1 <= arr1.length, arr2.length <= 5 * 104
1 <= arr1[i], arr2[i] <= 108
Solution
class TrieNode {
public:
TrieNode* children[10];
TrieNode(){
for(auto& child:children)
child = nullptr;
}
};
class Trie{
public:
TrieNode* root;
Trie(){
root = new TrieNode();
}
void insert(int num){
TrieNode* temp = root;
string str = to_string(num);
for(char ch:str){
int index = ch-'0';
if(!temp->children[index])
temp->children[index] = new TrieNode();
temp = temp->children[index];
}
}
int findLongPrefix(int num){
TrieNode* temp = root;
string str = to_string(num);
int len = 0;
for(char ch:str){
int index = ch -'0';
if(temp->children[index]){
len++;
temp = temp->children[index];
}
else
break;
}
return len;
}
};
class Solution {
public:
int longestCommonPrefix(vector<int>& arr1, vector<int>& arr2) {
Trie t;
for(int num: arr1)
t.insert(num);
int res = 0;
for(int num:arr2){
res = max(res,t.findLongPrefix(num));
}
return res;
}
};
Complexity Analysis
| Algorithm | Time Complexity | Space Complexity |
| --------- | --------------- | ---------------- |
| Trie | O(nm logm) | O(nm) |
Explanation
Intial Thoughts
To solve this problem, think of comparing strings, consider using a data structure like a trie to store and compare prefixes efficiently. The key idea is to find a common prefix between two sets of numbers, so focus on how to store and compare these numbers in a way that allows for efficient prefix matching. Consider breaking down the problem into smaller steps, such as inserting numbers from one array into the trie and then checking for prefixes from the other array. Key points to consider include how to efficiently insert numbers into the trie, how to find the longest common prefix, and how to handle cases where no common prefix exists.
Intuitive Analysis
Imagine you’re building a tree where each branch represents a digit in a number. For each number in the first array, you add its digits to the tree, creating new branches as needed. Then, for each number in the second array, you follow the branches in the tree as far as you can, counting how many digits match. The longest match you find is your answer. Think about how this process can be optimized, such as stopping as soon as you find a mismatch, and how to compare the lengths of the common prefixes found for each pair of numbers to determine the overall longest common prefix. Consider using the trie data structure to store the numbers from the first array and then checking for prefixes from the second array, focusing on the steps involved in inserting numbers into the trie and checking for the longest common prefix.
1. Intuition
- The problem requires finding the longest common prefix between all pairs of integers from two arrays, which suggests using a data structure that efficiently stores and retrieves prefixes.
- A Trie data structure is suitable for this problem as it allows for fast insertion and searching of prefixes.
- The Trie will be constructed using the integers from the first array, and then the integers from the second array will be used to find the longest common prefix.
- The key insight is that the longest common prefix will be the longest path in the Trie that matches a prefix of an integer from the second array.
- This approach works because the Trie ensures that all prefixes are stored in a way that allows for efficient searching.
- The algorithmic choice of using a Trie provides a time complexity of O(n*m) where n is the number of integers in the first array and m is the maximum number of digits in an integer.
- The space complexity is also O(n*m) due to the storage of the Trie.
2. Implementation
- The
TrieNode
class is used to represent each node in the Trie, with an arraychildren
to store the child nodes. - The
Trie
class has aninsert
method that uses theto_string
function to convert the integer to a string and then iterates over each character to insert it into the Trie. - The
findLongPrefix
method in theTrie
class is used to find the longest common prefix by iterating over each character of the integer and checking if it exists in the Trie. - The
longestCommonPrefix
function in theSolution
class constructs the Trie using the integers from the first array and then finds the longest common prefix for each integer in the second array. - The
max
function is used to keep track of the longest common prefix found so far. - The
for
loops are used to iterate over the integers in the arrays and the characters in the integers. - The
if
statement is used to check if a child node exists in the Trie before moving to the next character.
Complexity Analysis
Time Complexity:
- The
insert
operation in the Trie has a time complexity of O(logm) where m is the number of digits in the number, because in the worst case, we need to traverse the entire number as a string. Since we are doing this for n numbers, the total time complexity for inserting all numbers is O(n*logm). - The
findLongPrefix
operation also has a time complexity of O(logm) because we are potentially traversing the entire number as a string. Since we are doing this for all numbers in the second array, the total time complexity for finding all prefixes is O(n*logm). - Therefore, the overall time complexity of the algorithm is O(nlogm) + O(nlogm) = O(nlogm) + O(nmlogm) = O(nm*logm) due to the iteration over all numbers in both arrays and the string conversion of numbers to find the prefix length.
Space Complexity:
- The space complexity of the Trie data structure is determined by the total number of nodes it contains. In the worst case, if all numbers in the array are unique and have the maximum possible number of digits, the Trie can have up to n*m nodes where n is the number of numbers and m is the maximum number of digits in a number.
- Each node in the Trie has a fixed number of children (10 in this case), so the space complexity per node is constant. Therefore, the overall space complexity of the Trie is O(n*m).
- Additionally, the space required for storing the input arrays and other variables is negligible compared to the space required by the Trie, so the overall space complexity of the algorithm is O(n*m).
Footnote
This question is rated as Medium difficulty.
Hints
Put all the possible prefixes of each element in
arr1
into a HashSet.
For all the possible prefixes of each element in
arr2
, check if it exists in the HashSet.
Similar Questions:
Title | URL | Difficulty |
---|---|---|
Longest Common Prefix | https://leetcode.com/problems/longest-common-prefix | Easy |
Longest Common Suffix Queries | https://leetcode.com/problems/longest-common-suffix-queries | Hard |