14.最长公共前缀
难度:简单
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串“”。
示例 1:
- 输入: [“flower”, “flow”, “flight”]
- 输出: “fl”
示例 2:
- 输入: [“dog”, “racecar”, “car”]
- 输出: “”
- 解释: 输入不存在公共前缀。
说明: 所有输入只包含小写字母 a-z 。
def longest_common_prefix1(strs):
"""水平扫描
复杂度分析:
时间复杂度:O(S),S 是所有字符串中字符数量的总和。
最坏的情况下,n个字符串都是相同的。算法会将 S1 与其他字符串 [S2...Sn] 都做一次比较。
这样就会进行 S 次字符比较,其中 S 是输入数据中所有字符数量。
空间复杂度:O(1)
"""
assert(isinstance(strs, list))
if len(strs) == 0:
return ''
prefix = strs[0]
for s in strs[1:]:
while not s.startswith(prefix):
prefix = prefix[0:len(prefix) - 1]
if not prefix:
return ''
return prefix
def longest_common_prefix2(strs):
"""水平扫描
"""
assert(isinstance(strs, list))
slen = len(strs)
if slen == 0:
return ''
for i, c in enumerate(strs[0]):
for j in range(1, slen):
if i == len(strs[j]) or strs[j][i] != c:
return strs[0][0:i]
return strs[0]
class Solution(object):
def longest_common_prefix(self, strs):
"""分治法
"""
assert(isinstance(strs, list))
slen = len(strs)
if slen == 0:
return ''
return self._longest_common_prefix(strs, 0, slen - 1)
def _longest_common_prefix(self, strs, l, r):
if l == r:
return strs[l]
mid = (l + r) // 2
left = self._longest_common_prefix(strs, l, mid)
right = self._longest_common_prefix(strs, mid + 1, r)
return self._common_prefix(left, right)
def _common_prefix(self, left, right):
minval = min(len(left), len(right))
for i in range(minval):
if left[i] != right[i]:
return left[0:i]
return left[0:minval]
def longest_common_prefix4(strs):
"""二分查找法
复杂度分析:
最坏情况下,我们有 n 个长度为 m 的相同字符串。
时间复杂度:O(S*log(n)),其中 S 所有字符串中字符数量的总和。
算法一共会进行 log(n) 次迭代,每次一都会进行 S = m*n 次比较,所以总时间复杂度为 O(S*log(n))。
空间复杂度:O(1),我们只需要使用常数级别的额外空间。
"""
assert(isinstance(strs, list))
if len(strs) == 0:
return ''
min_len = 2**31 - 1
for s in strs:
min_len = min(min_len, len(s))
low, high = 1, min_len
while low <= high:
middle = (low + high) // 2
if is_common_prefix(strs, middle):
low = middle + 1
else:
high = middle - 1
return strs[0][0:(low + high) // 2]
def is_common_prefix(strs, mid):
s, l = strs[0][0:mid], len(strs)
for i in range(l):
if not strs[i].startswith(s):
return False
return True
strs1 = ["flower","flow","flight"]
strs2 = ["dog","racecar","car"]
strs3 = ["ccc", "ccc", "ccc"]
# print(longest_common_prefix1(strs1))
# print(longest_common_prefix1(strs2))
%time longest_common_prefix1(strs1)
%time longest_common_prefix2(strs1)
# print(longest_common_prefix2(strs1))
# print(longest_common_prefix2(strs2))
# print(longest_common_prefix2(strs3))
# Output:
# CPU times: user 9 µs, sys: 0 ns, total: 9 µs
# Wall time: 11.4 µs
# CPU times: user 77 µs, sys: 0 ns, total: 77 µs
# Wall time: 25.3 µs
# 'fl'
testcases = [strs1, strs2, strs3]
s = Solution()
for tc in testcases:
val = s.longest_common_prefix(tc)
print(val)
break
# Output:
# fl
print(longest_common_prefix4(strs1))
print(longest_common_prefix4(strs2))
print(longest_common_prefix4(strs3))
# Output:
# fl
#
# ccc