[LeetCode] 014. Longest Common Prefix
-
date_range Mar. 29, 2019 - Friday info
- Problem (Easy)
- Approach 1: Vertical Scanning
- Approach 2: Horizontal Scanning
- Approach 3: Divide and Conquer
- Approach 4: Binary Search
Problem (Easy)
Write a function to find the longest common prefix string amongst an array of strings.
If there is no common prefix, return an empty string “”.
Example 1:
- Input: [“flower”,”flow”,”flight”]
- Output: “fl”
Example 2:
- Input: [“dog”,”racecar”,”car”]
- Output: “”
- Explanation: There is no common prefix among the input strings.
Note:
All given inputs are in lowercase letters a-z
.
Approach 1: Vertical Scanning
Idea
Scan all the strings in the list character by charcter columnwise. if all characters in the column are the same, add it to LCP, else, return current LCP directly.
Solution
class Solution1:
def longestCommonPrefix(self, strs):
"""
:type strs: List[str]
:rtype: str
"""
if not len(strs):
return ''
ret = ''
for i in range(min([len(s) for s in strs])):
for s in strs[1:]:
if strs[0][i] != s[i]:
return ret
ret += strs[0][i]
return ret
Complexity
- Time: $O(S)$, where $S$ is the sum of the all characters.
- Space: $O(1)$. We only need constant extra space.
Approach 2: Horizontal Scanning
Idea
Find the LCP of each pair of strings in loops.
Solution
class Solution2:
def longestCommonPrefix(self, strs):
"""
:type strs: List[str]
:rtype: str
"""
if not len(strs):
return ''
ret = strs[0]
for s in strs[1:]:
ret = ret[:min(len(ret), len(s))]
for i in range(len(ret)):
if ret[i] != s[i]:
ret = ret[:i]
break
return ret
Complexity
- Time: $O(S)$
- Space: $O(1)$
Approach 3: Divide and Conquer
Idea
Solution
class Solution3:
def longestCommonPrefix(self, strs):
"""
:type strs: List[str]
:rtype: str
"""
if not len(strs):
return ''
return self.recurse(strs)
def recurse(self, strs):
if len(strs) == 1:
return strs[0]
mid = len(strs) // 2
lcpLeft = self.recurse(strs[:mid])
lcpRight = self.recurse(strs[mid:])
return self.commonPrefix(lcpLeft, lcpRight)
def commonPrefix(self, str1, str2):
ret = str1[:min(len(str1), len(str2))]
for i in range(len(ret)):
if ret[i] != str2[i]:
ret = ret[:i]
break
return ret
Complexity
- Time: $O(S)$, where $S=m*n$. In the best case, it’s $O(minLen\cdot n)$, where $minLen$ is the shortest string of the array.
- Space: $O(m\cdot \log(n))$.
Approach 4: Binary Search
Idea
The idea is to apply binary search method to find the string with maximum value L
,
Solution
class Solution4:
def longestCommonPrefix(self, strs):
"""
:type strs: List[str]
:rtype: str
"""
if not len(strs):
return ''
minLen = min([len(s) for s in strs])
low, high = 0, minLen
while low <= high:
mid = (low + high) // 2
if self.isCommonPrefix(strs, mid):
low = mid + 1
else:
high = mid -1
return strs[0][:(low+high) // 2]
def isCommonPrefix(self, strs, l):
str1 = strs[0][:l]
for s in strs[1:]:
if not s.startswith(str1):
return False
return True
Complexity
- Time: $O(S\cdot\log(n))$
- Space: $O(1)$
KF