LeetCode | 14. Longest Common Prefix的三種演算法
問題
Write a function to find the longest common prefix string amongst an array of strings.
Solution 1: Binary Search Using Recursion
大概的思路是:首先找到input中string的最小長度L,然後把每個string從L/2處一分為二,先比較[0, L/2]是否是common prefix。如果前一半是,則比較[L/2+1, 3/4*L];如果前一半不是,則比較[0,L/4]。
在下面這個implementation中,由於recursion完全在checkPrefix
這個函式中進行,且在每一層會call這個函式兩次,因此不是很efficient。
def longestCommonPrefix(self, strs: List[str]) -> str:
try:
n = np.min([len(word) for word in strs])
except ValueError:
return ''
if n==0:
return ''
strs = [word[:n] for word in strs]
re = checkPrefix(strs, l=0, r=n)
return strs[0][:re]
def checkPrefix(self, strs, l, r):
# stop case
if l == r-1:
first = strs[0]
for word in strs:
if word[l]!=first[l]:
return l
return r
else:
mid = l + math.ceil((r-l)/2)
# recursive call 1
if checkPrefix(strs, l, mid)==mid:
# recursive call 2
return checkPrefix(strs, mid, r)
else:
return checkPrefix(strs, l, l + math.ceil((r-l)/4))
Complexity Analysis:
- L是input中最小的string長度,S是input string長度之和,則binary search algorithm的time complexity為O(log(L)*S)。這是因為總共會做O(log(L))次comparisons,而每次比較prefix都需要O(S)。
- Space Complexity是O(log(L)),因為總共有O(log(L))個recursive calls,而每個的儲存空間是O(1)。
Solution 2: Iterative Binary Search
改進後的implementation不使用recursion,而是用l
和r
兩個pointers,且在checkPrefix
函式只進行prefix的比對。這樣的速度快了很多:
def longestCommonPrefix(self, strs: List[str]) -> str:
try:
n = np.min([len(word) for word in strs])
except ValueError:
return ''
if n==0:
return ''
strs = [word[:n] for word in strs]
l = 0
r = n - 1
while l<=r:
mid = math.ceil((l + r)/2)
if checkPrefix(strs, l, mid):
l = mid + 1
else:
r = mid - 1
return strs[0][:r+1]
def checkPrefix(self, strs, l, r):
first = strs[0][l:r+1]
for word in strs:
if first!=word[l:r+1]:
return False
return True
Complexity Analysis:
- Time complexity同上,O(log(L)*S)。
- Space Complexity O(1)。
Solution 3: Vertical Scanning
思路很簡單:把input的所有詞豎著排列起來,從最左邊開始,每次比較一個character。
(其實仔細分析一下,vertical scanning應該是最intuitive、最好implement、同時還最快的algorithm了,不知道為什麼自己的第一反應是捨近求遠去弄最不方便的recursive binary search……)
# deal with edge cases
try:
n = np.min([len(word) for word in strs])
except ValueError:
return ''
if n==0:
return ''
if len(strs)==1:
return strs[0]
strs = [word[:n] for word in strs]
# start scanning
for i in range(n):
first = strs[0][i]
for word in strs[1:]:
if word[i]!=first:
return strs[0][:i]
return strs[0]
Complexity Analysis
- Time complexity O(S),因為worst case不過是把input裡的所有character都比對一遍罷了。
- Space complexity O(1)。
相關文章
- Leetcode Longest Common PrefixLeetCode
- [LeetCode]Longest Common PrefixLeetCode
- Leetcode 14 Longest Common PrefixLeetCode
- Leetcode-Longest Common PrefixLeetCode
- Longest Common Prefix leetcode javaLeetCodeJava
- LeetCode 第 14 題(Longest Common Prefix)LeetCode
- LeetCode解題-#14-Longest Common PrefixLeetCode
- [LeetCode] Longest Common Prefix 最長共同字首LeetCode
- C# 寫 LeetCode easy #14 Longest Common PrefixC#LeetCode
- leetcode學習筆記14 Longest Common PrefixLeetCode筆記
- LeetCode Longest Common Prefix(014)解法總結LeetCode
- LeetCode - 014 - 最長公共字首(longest-common-prefix)LeetCode
- Longest Common Prefix字串最長公共字首問題字串
- LintCode-Longest Common Subsequence
- LintCode-Longest Common Substring
- LeetCode- Implement Trie (Prefix Tree)LeetCode
- Leetcode 32 Longest Valid ParenthesesLeetCode
- LeetCode- Longest Absolute File PathLeetCode
- LeetCode-Longest Increasing SubsequenceLeetCode
- Leetcode Longest Palindromic SubstringLeetCode
- Leetcode-Longest Valid ParenthesesLeetCode
- Leetcode-Longest Consecutive SequenceLeetCode
- leetcode 之 Longest Valid ParenthesesLeetCode
- Longest Valid Parentheses leetcode javaLeetCodeJava
- Longest Consecutive Sequence leetcode javaLeetCodeJava
- leetcode388. Longest Absolute File PathLeetCode
- [LeetCode] 5. Longest Palindromic SLeetCode
- [LeetCode] 32. Longest Valid ParenthesesLeetCode
- LeetCode 5 (Longest Palindromic Substring)LeetCode
- leetcode32_Longest Valid ParenthesesLeetCode
- LeetCode-Longest Increasing Path in a MatrixLeetCode
- Leetcode-Longest Palindromic SubstringLeetCode
- Longest Palindromic Substring leetcode javaLeetCodeJava
- Leetcode 329. Longest Increasing Path in a MatrixLeetCode
- LeetCode 5. Longest Palindromic SubstringLeetCode
- LeetCode OJ : 5 Longest Palindromic SubstringLeetCode
- LeetCode128:Longest Consecutive SequenceLeetCode
- Leetcode Longest Substring Without Repeating CharactersLeetCode