14. Longest Common Prefix
Title
編寫一個函數來查找字符串數組中的最長公共前綴。
如果不存在公共前綴,返回空字符串 “”。
Solve
1.橫向掃描
用LCP(S1 …Sn)表示字符串S1 …Sn的最長公共前綴,可以得到以下結論:LCP(S1…Sn)=LCP(LCP(LCP(S1,S2),S3),…Sn)LCP(S_1…S_n)=LCP(LCP(LCP(S_1,S_2),S_3),…S_n)LCP(S1?…Sn?)=LCP(LCP(LCP(S1?,S2?),S3?),…Sn?)
依次遍歷字符串數組中的每個字符串,對于每個遍歷到的字符串,更新最長公共前綴,當遍歷完所有的字符串以后,即可得到字符串數組中的最長公共前綴。
優化: 如果在尚未遍歷完所有的字符串時,最長公共前綴已經是空串,則最長公共前綴一定是空串,因此不需要繼續遍歷剩下的字符串,直接返回空串即可。
Code
def longestCommonPrefix_transverseScan(self, strs: List[str]) -> str:def lcp(str1, str2):index, length = 0, min(len(str1), len(str2))while index < length and str1[index] == str2[index]:index += 1return str1[: index]if not strs:return ""prefix = strs[0]for i in range(1, len(strs)):prefix = lcp(prefix, strs[i])if not prefix:breakreturn prefix時間復雜度
- 時間復雜度: O(mn),其中m是字符串數組中的字符串的平均長度,n是字符串的數量,最壞情況下,字符串數組中的每個字符串的每個字符都會被比較一次。
- 空間復雜度: O(1),使用額外空間復雜度為常數。
2.縱向掃描
縱向掃描時,從前往后遍歷所有字符串的每一列,比較相同列上的字符是否相同,如果相同則繼續對下一列進行比較,如果不相同則當前列不再屬于公共前綴,當前列之前的部分為最長公共前綴。
↓↓ flower↓↓ flow↓↓ flightCode
def longestCommonPrefix_longitudinalScan(self, strs: List[str]) -> str:if not strs:return ""for i in range(len(strs[0])):char = strs[0][i]for j in range(1, len(strs)):if i == len(strs[j]) or strs[j][i] != char:return strs[0][:i]return strs[0]時間復雜度
- 時間復雜度: O(mn),其中m是字符串數組中的字符串的平均長度,n是字符串的數量,最壞情況下,字符串數組中的每個字符串的每個字符都會被比較一次。
- 空間復雜度: O(1),使用額外空間復雜度為常數。
3.分治法
LCP 的計算滿足結合律,可以有以下推導:LCP(S1…Sn)=LCP(LCP(S1,…Sk),LCP(Sk+1,…Sn))LCP(S_1…S_n)=LCP(LCP(S_1,…S_k),LCP(S_{k+1},…S_n))LCP(S1?…Sn?)=LCP(LCP(S1?,…Sk?),LCP(Sk+1?,…Sn?))
基于上述推導,可以使用分治法得到字符串數組中的最長公共前綴。
對于問題 LCP(Si ?Sj),可以分解成兩個子問題 LCP(Si…Smid) 與 LCP(Smid+1?…Sj),其中 mid= (i+j)/2,對兩個子問題分別求解,然后對兩個子問題的解計算最長公共前綴,即為原問題的解。
Code
def longestCommonPrefix_divideAndConquer(self, strs: List[str]) -> str:def lcp(left, right):if left == right:return strs[left]middle = (left + right) // 2leftLcp, rightLcp = lcp(left, middle), lcp(middle + 1, right)minLength = min(len(leftLcp), len(rightLcp))for i in range(minLength):if leftLcp[i] != rightLcp[i]:return leftLcp[:i]return leftLcp[: minLength]return "" if not strs else lcp(0, len(strs) - 1)時間復雜度
- 時間復雜度: O(mn),其中m是字符串數組中的字符串的平均長度,n是字符串的數量。時間復雜度的遞推式是T(n)=2T(n/2)+O(m),通過計算可得 T(n)=O(mn)。
- 空間復雜度: O(mlogn),其中 m 是字符串數組中的字符串的平均長度,n 是字符串的數量。空間復雜度主要取決于遞歸調用的層數,層數最大為 logn,每層需要 m 的空間存儲返回結果。
4.Python內置函數
zip() 函數用于將可迭代的對象作為參數,將對象中對應的元素打包成一個個元組,然后返回由這些元組組成的列表。
如果各個迭代器的元素個數不一致,則返回列表長度與最短的對象相同,利用 * 號操作符,可以將元組解壓為列表。
def longestCommonPrefix_python(self, strs: List[str]) -> str:for index, value in enumerate((*(len(set(item)) for item in zip(*strs)), 2)):if value > 1:return (*strs, "")[0][: index]總結
以上是生活随笔為你收集整理的14. Longest Common Prefix的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 我的地盘我做主——你必须遵守的Pytho
- 下一篇: 297. Serialize and D