序言
今天是刷LT的一天,好好干饭,好好努力,好好加油哦!
- 第一题
题目描述:
找到几个字符串中最长公共前缀。
例子如下:
Input: ["flower","flow","flight"]
Output: "fl"
Input: ["dog","racecar","car"]
Output: ""
方法一
解析思路:
这里需要使用的的是zip函数和set函数,先理解这两个函数的用法再做这道题。
(1) zip() vs zip(*)
zip()函数作用于可迭代的对象,将对象对应的元素组成一个个元组
然后返回这些元组的列表, 例子如下:
a = [1, 2, 3]
b = ["a", "b", "c"]
list(zip(a, b)) #用list列出来
输出为:[(1, 'a'), (2, 'b'), (3, 'c')]
zip(*)函数则相反,起到解压的作用,
例子如下:
example = ["flower", "flow", "flqwe"]
list(zip(*example))
输出为:[('f', 'f', 'f'), ('l', 'l', 'l'), ('o', 'o', 'q'), ('w', 'w', 'w')]
(2)set()函数
set() 函数创建一个无序不重复元素集,可用于删除重复值。例子如下
a = set('abcdd')
b = set('cdeff')
a
b
输出为:
{
'a', 'b', 'c', 'd'}
{
'c', 'd', 'e', 'f'}
a & b #交集
输出为 {
'c', 'd'}
a | b #并集
输出为 {
'a', 'b', 'c', 'd', 'e', 'f'}
回到之前的题目,需要返回列表中的几个字符中共同前缀。
Input: ["flower","flow","flight"]
Output: "fl"
首先,用zip(*)把列表的几个字符解压出来,把input解压出来,变成[(‘f’, ‘f’, ‘f’), (‘l’, ‘l’, ‘l’), (‘o’, ‘o’, ‘q’), (‘w’, ‘w’, ‘w’)], 然后用set函数去掉重复值,变成[(‘f’), (‘l’), ( ‘o’, ‘q’), (‘w’)],最后用一个if函数,只取其中set后长度为1的字符。Python如下:
def longestCommonPrefix(strs) -> str:
opt = ''
for i in zip (*strs): #zip (*strs) 即是解压组合出来
if len(set(i))==1: #针对set后长度为1的字符
opt += i[0] #录入字符
else:
break
return opt
方法二:
把列表的第一个字符串作为标准,跟剩余的其他字符串比较。而两个字符串的比较使用二分法来比较,最后的时间复杂度为O(N*log(N))。跟第一个方法的时间复杂度相比好很多。
使用一个例子来理解两个字符串的二分法是:
str = {leets, leetcode, leetc, leed}
首先,leets 从中间拆开,5//2 = 2 即leets 分为 lee 和 ts
然后,检查lee 是否 in {leetcode, leetc, leed} 一致通过
再然后,把t加入lee 为leet,再次检查leet 是否 in {leetcode, leetc, leed} 并没有一致通过
所以直接返回 lee为最长公共前缀。用这个方法执行起来更快。
首先理解find函数用法,可以检测字符串中是否包含子字符串
find()函数语法 :string.find(str, beg=0, end=len(string))
- str : 指定检索的字符串
- beg :开始索引,默认为0
- end :结束索引,默认为字符串的长度
如果指定 beg(开始) 和 end(结束) 范围,则检查是否包含在指定范围内
如果包含子字符串返回开始的索引值,否则返回-1
例子:
str1 = "AppleandDoctor"
str2 = "and"
print(str1.find(str2)) #没有任何指定范围,默认整个字符串范围
print(str1.find(str2, 1)) #指定从位置为1的开始检索
print(str1.find(str2, 10)) #指定从位置为10的开始检索
输出
5
5
-1
所以定义PassorNot函数 检测字符是否全部通过
def PassorNot(strs,mid):
s = strs[0][0:mid]
#检测剩余的其他字符串
for i in range(1,len(strs)):
#如果出现了不通过的情况,则马上return false
if strs[i].find(s)!=0:
return False
#如果都通过,即剩余的字符串都包含s,则return True
return True
现在可以定义整个函数
def longestCommonPrefix(strs):
'''
:strs: List type 包含多个字符串的列表
返回最长的公共前缀
'''
#取列表中的第一个字符串作为标准比较
low, high = 1,len(strs[0])
while low <= high:
mid = (low + high)//2
if PassorNot(strs,mid):
low = mid + 1
else:
high = mid - 1
return strs[0][0:(low+high)//2]
- 题目二
题目描述:
给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1。
例子如下:
输入: haystack = "hello", needle = "ll"
输出: 2
输入: haystack = "aaaaa", needle = "bba"
输出: -1
解析思路:
直接根据条件来,用多个if 来筛选。
def strStr(haystack,needle):
lh = len(haystack) #haystack的长度
ln = len(needle) #needle的长度
if ln == 0: #当needle为空集return0
return 0
if lh == 0 or lh < ln: #当不符合条件无法查找 return -1
return -1
i = 0
while(i<=lh-ln):
if haystack[i] == needle[0]:
#当出现和needle第一个字母相同的字符时,测试后面的是否一致。
if haystack[i:i+ln] == needle:
#记住[i:i+ln]字符提取是取前不取后,即i+ln的字符是没有取到的。
return i
else:
i+=1
else:
i+=1
return -1