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 14 Longest Common PrefixLeetCode
- LeetCode Longest Common Prefix(014)解法總結LeetCode
- C# 寫 LeetCode easy #14 Longest Common PrefixC#LeetCode
- leetcode學習筆記14 Longest Common PrefixLeetCode筆記
- LeetCode - 014 - 最長公共字首(longest-common-prefix)LeetCode
- 最長公共子序列 Longest Common Subsequence
- SPOJ 1811 Longest Common Substring(字尾自動機)
- Leetcode 32 Longest Valid ParenthesesLeetCode
- LeetCode 5 (Longest Palindromic Substring)LeetCode
- [LeetCode] 32. Longest Valid ParenthesesLeetCode
- [LeetCode] 5. Longest Palindromic SLeetCode
- Leetcode 3 Longest Substring Without Repeating CharactersLeetCode
- [LeetCode] 674. Longest Continuous Increasing SubsequenceLeetCode
- Leetcode 298 Binary Tree Longest Consecutive SequenceLeetCode
- Leetcode 329. Longest Increasing Path in a MatrixLeetCode
- [LeetCode] 2831. Find the Longest Equal SubarrayLeetCode
- leetcode388. Longest Absolute File PathLeetCode
- [LeetCode] 2419. Longest Subarray With Maximum Bitwise ANDLeetCode
- LeetCode之Find Common Characters(Kotlin)LeetCodeKotlin
- [LeetCode] 524. Longest Word in Dictionary through DeletingLeetCode
- Leetcode 3. Longest Substring Without Repeating CharactersLeetCode
- [LeetCode] 2414. Length of the Longest Alphabetical Continuous SubstringLeetCodeAlphabet
- LeetCode Greatest Common Divisor of Strings All In OneLeetCode
- Leetcode javascript 3 longest-substring-without-repeating-charactersLeetCodeJavaScript
- LeetCode Longest Substring Without Repeating Characters(003)解法總結LeetCode
- [LeetCode] 3. Longest Substring Without Repeating Characters 題解LeetCode
- Leetcode 329. Longest Increasing Path in a Matrix (python+cpp)LeetCodePython
- Leetcode5: Longest Palindromic Substring(最長迴文子串)LeetCode
- 漫畫:三種 “奇葩” 的排序演算法排序演算法
- 【Leetcode】3. Longest Substring Without RepeatingCharacters無重最長子串LeetCodeGC
- LeetCode3:Longest Substring Without Repeating Characters(無重複字元的最長子串)LeetCode字元
- 【leetcode】32. Longest Valid Parentheses 最長的有效匹配括號子串長度LeetCode
- E - Prefix Equality
- leetcode刷題記錄:演算法(三)滑動視窗演算法LeetCode演算法
- 三種梯度下降演算法的區別(BGD, SGD, MBGD)梯度演算法
- 三種高階比較排序演算法排序演算法
- FIFO/LRU/LFU三種快取演算法快取演算法
- IP-Prefix List