当前位置:网站首页>LeetCode #14. 最长公共前缀
LeetCode #14. 最长公共前缀
2022-07-29 05:24:00 【张楚明ZCM】

方法一:横向扫描比较
思路:先将第一个字符串作为最长公共前缀,然后逐个和后面的字符串比较,记录新的最长公共前缀,直到全部遍历完成可得全部字符串的最长公共前缀。

先写比较函数LCP
取两个字符串中较小的并测量其长度。
利用循环比较两者中每一个元素的值,相等则指针index往后增加,一旦发现不相等则立刻跳出,最后返回前面相同的部分即为公共前缀。
def LCP(self, str_1, str_2):
n = len(min(str_1, str_2))
index = 0
for i in range(0, n):
if str_1[i] == str_2[i]:
index += 1
else:
break
return str_1[:index]然后是主函数longestCommonPrefix,先假定第一个字符串最为最长公共前缀,然后利用LCP函数和后面的字符串比较。将结果返回。
如果发现比较结果为空则立即跳出循环,不必再比较后面的字符串了,因为已经没有公共部分了。
if not max_com_prefix:
break全部代码如下
from typing import List
class Solution:
def longestCommonPrefix(self, strs: List[str]) -> str:
if not strs:
return ""
count = len(strs)
max_com_prefix = strs[0]
for i in range(1, count):
max_com_prefix = self.LCP(max_com_prefix, strs[i])
if not max_com_prefix:
break
return max_com_prefix
def LCP(self, str_1, str_2):
n = len(min(str_1, str_2))
index = 0
for i in range(0, n):
if str_1[i] == str_2[i]:
index += 1
else:
break
return str_1[:index]
if __name__ == "__main__":
a = Solution()
str_test01 = ["flower","flow","flight"]
print(a.longestCommonPrefix(str_test01))方法二:纵向扫描比较
思路:将所有数字中所有的字符串全部拿出来,依次比较每一个字符串中的字符。如果全部相等则比较下一字符,一旦发现有不相等的,立刻停止扫描。前面部分即为最大公共前缀。
先将数组中的第一个字符串的长度作为默认的最大前缀长度
length=len(strs[0])然后将计算数组中字符串是个数
count = len(strs)重点循环部分
将第一个字符串的第i个字符作为比较的基准,比较每个字符串的第i个字符是否与它相同。
一旦发现第j个字符串的第i个字符与第一个字符串的第i个字符不相等,或者i刚好为第j个字符串的长度,则立即返回第一个字符串的前i个字符,即为最大公共前缀。
i在循环中不断增大,当i等于第j个字符串的长度时,说明该字符串已经遍历完成了,最大公共前缀不可能超过其中最小字符串的全部字符,所以应当立即返回第一个字符串的前i个字符,否则会有溢出错误。
for i in range(length):
for j in range(1, count):
if i == len(strs[j]) or strs[0][i] != strs[j][i]:
return strs[0][:i]
return strs[0]也可以写成如下样式
for i in range(length):
c = strs[0][i]
if any(i == len(strs[j]) or strs[j][i] != c for j in range(1, count)):
return strs[0][:i]
return strs[0]any()函数参见
完整代码如下
from typing import List
class Solution:
def longestCommonPrefix(self, strs: List[str]) -> str:
if not strs:
return ""
length=len(strs[0])
count = len(strs)
for i in range(length):
for j in range(1, count):
if i==len(strs[j]) or strs[0][i] != strs[j][i]:
return strs[0][:i]
return strs[0]
if __name__ == "__main__":
a = Solution()
str_test01 = ["flower", "flow", "flight"]
print(a.longestCommonPrefix(str_test01))
另一种完整代码
from typing import List
class Solution:
def longestCommonPrefix(self, strs: List[str]) -> str:
if not strs:
return ""
length=len(strs[0])
count = len(strs)
for i in range(length):
c = strs[0][i]
if any(i == len(strs[j]) or strs[j][i] != c for j in range(1, count)):
return strs[0][:i]
return strs[0]
if __name__ == "__main__":
a = Solution()
str_test01 = ["flower", "flow", "flight"]
print(a.longestCommonPrefix(str_test01))
利用zip函数
实现zip函数.
方法三:分治法
比较函数LCP满足结合律:

于是可以将一整段数字字符串分成两组比较,然后再将两者的结果比较得出最终结果。
而每一组又可以这样分成两组,不停的迭代。
from typing import List
class Solution:
def longestCommonPrefix(self, strs: List[str]) -> str:
def lcp(start, end):
if start == end:
return strs[start]
mid = (start + end) //2
lcp_left = lcp(start, mid)
lcp_right = lcp(mid+1, end)
mid_length = min(len(lcp_left), len(lcp_right))
for i in range(mid_length):
if lcp_left[i] != lcp_right[i]:
return lcp_left[:i]
return lcp_left[:mid_length]
return "" if not strs else lcp(0, len(strs)-1)
if __name__ == "__main__":
a = Solution()
str_test01 = ["flower", "flow", "flight"]
print(a.longestCommonPrefix(str_test01))
方法四:二分查找法
先写判断函数,判断给定长度的部分字符串是否相同。
def is_common_fix(length):
str0 = strs[0][:length]
count = len(strs)
for i in range (1, count):
if strs[i][:length] != str0:
return False
return True其中的for循环可以改写为三元表达式,利用all()函数迭代可以减少内存占用。
def is_common_fix(length):
str0 = strs[0][:length]
count = len(strs)
return all( str0 == strs[i][:length] for i in range (1, count))找到整个数字字符串的最小字符长度
min_length = min(len(s) for s in strs)然后循环二分并利用is_common_prefix()函数判断
low = 0
high = min_length
while low < high:
mid = low + (high - low) // 2
if is_common_prefix(mid):
low = mid
else:
high = mid - 1
return strs[0][:low]完整代码如下
from typing import List
class Solution:
def longestCommonPrefix(self, strs: List[str]) -> str:
def is_common_prefix(length):
str0 = strs[0][:length]
count = len(strs)
return all(strs[i][:length] == str0 for i in range (1, count))
if not str:
return ""
min_length = min(len(s) for s in strs)
low = 0
high = min_length
while low < high:
mid = low + (high - low) // 2
if is_common_prefix(mid):
low = mid
else:
high = mid - 1
return strs[0][:low]
if __name__ == "__main__":
a = Solution()
str_test01 = ["flower", "flow", "flight"]
print(a.longestCommonPrefix(str_test01))
方法五:利用max(),min()函数
from typing import List
class Solution:
def longestCommonPrefix(self, strs: List[str]) -> str:
if not strs: return ""
str0 = min(strs)
str1 = max(strs)
for i in range(len(str0)):
if str0[i] != str1[i]:
return str0[:i]
return str0
if __name__ == "__main__":
a = Solution()
str_test01 = ["flower", "flow", "flight"]
print(a.longestCommonPrefix(str_test01))方法六:利用zip()函数
zip()函数可以将数组中的元素分成一个一个的再对应打包。
*操作符可以将元组解压为列表
strs = ["flower", "flow", "flight"]
x = zip(strs)
y = zip(*strs)
print(x)
print(y)
print(list(x))
print(list(y))
结果如下
<zip object at 0x000002C0587005C8>
<zip object at 0x000002C058936188>
[('flower',), ('flow',), ('flight',)]
[('f', 'f', 'f'), ('l', 'l', 'l'), ('o', 'o', 'i'), ('w', 'w', 'g')]set()函数可以将重复的元素合并为同一个
str1 = ["a", "a", "a"]
str2 = ["a", "a", "b"]
str3 = ["a", "b", "c"]
x = set(str1)
y = set(str2)
z = set(str3)
print(x)
print(y)
print(z)结果如下
{'a'}
{'b', 'a'}
{'c', 'b', 'a'}所以最后的完整代码如下
from typing import List
class Solution:
def longestCommonPrefix(self, strs: List[str]) -> str:
ans = ''
for i in list(zip(*strs)):
if len(set(i)) == 1:
ans += i[0]
else:
break
return ans
if __name__ == "__main__":
a = Solution()
str_test01 = ["flower", "flow", "flight"]
print(a.longestCommonPrefix(str_test01))
扩展
自己实现zip函数
def my_zip(*args):
min_len = min(len(item) for item in args)
index = 0
while index < min_len:
new_item_list = [item[index] for item in args]
index += 1
yield tuple(new_item_list)tuple()将列表转换为元组
Python Tuple(元组) tuple()方法 | 菜鸟教程
yield() 迭代器
*args:可以理解为只有一列的表格,长度不固定。
**kwargs:可以理解为字典,长度也不固定。
边栏推荐
- QT learning notes - Import and export of Excel
- 循环链表和双向链表
- 物联网倾斜监测解决方案
- 【RoboMaster】A板接收JY-ME01角度传感器数据--modebus协议&CRC软件校验
- Hal library learning notes - 9 DMA
- 【软件工程之美 - 专栏笔记】22 | 如何为项目做好技术选型?
- NoClassDefFoundError 处理
- HR must ask questions - how to fight with HR (collected from FPGA Explorer)
- 【软件工程之美 - 专栏笔记】“一问一答”第3期 | 18个软件开发常见问题解决策略
- Reading papers on fake news detection (2): semi supervised learning and graph neural networks for fake news detection
猜你喜欢

Jingwei Qili: OLED character display based on hmep060 (and Fuxi project establishment demonstration)

【软件工程之美 - 专栏笔记】14 | 项目管理工具:一切管理问题,都应思考能否通过工具解决

智能货架安全监测系统

【软件工程之美 - 专栏笔记】27 | 软件工程师的核心竞争力是什么?(上)

Power electronics: single inverter design (matlab program +ad schematic diagram)

Hal library learning notes-14 ADC and DAC

Ml self study notes 5

Jingwei Qili: development of heart rate and blood oxygen module based on hmep060 (1: FPGA sends multi bit instructions)

Reading papers on false news detection (5): a semi supervised learning method for fake news detection in social media

顺序表和链表
随机推荐
JUC concurrent knowledge points
Ml8 self study notes LDA principle formula derivation
Dust and noise monitoring system
Ml6 self study notes
CV520国产替代Ci521 13.56MHz 非接触式读写器芯片
八大排序-----------快速排序
Open source based on STM32: MHD Bluetooth speaker (including source code +pcb)
Huawei cloud 14 days Hongmeng device development -day1 environment construction
一些工具,插件,软件链接分享给大家~
Rowkey设计
动态加载数据
DP4301—SUB-1G高集成度无线收发芯片
【软件工程之美 - 专栏笔记】26 | 持续交付:如何做到随时发布新版本到生产环境?
Ml4 self study notes
DP1332E多协议高度集成非接触式读写芯片
智慧能源管理系统解决方案
LeetCode #189.轮转数组
利用云打码来破解登录遇到验证码的问题
无符号右移
智能货架安全监测系统