题目如下:题目链接
横向前缀判断法,维护一个res字符串,针对每一个字符串进行搜索最长公共前缀。
func longestCommonPrefix(strs []string) string {
alllen := len(strs)
if alllen==0{
return ""
}
res:=strs[0]
for i:=1;i<alllen;i++{//对每一个字符串,进行最长前缀对比,返回最长前缀
res = cp(res,strs[i])
if len(res)==0{
break
}
}
return res
}
func cp(a string,b string) string{ //最长前缀的最长长度总是最短的那个字符串
l:=min(len(a),len(b))
index:=0
for index<l && a[index]==b[index]{//对比返回最长前缀
index++
}
return a[:index]//因为访问字符串的单个位置返回的是一个字节,所以需要返回一个切片
}
func min(a int,b int) int{
if a<b{return a}
return b
}
纵向前缀判断法,每次都判断整个字符串中相同位置的字符,匹配成功才能进入到下一个字符
func longestCommonPrefix(strs []string) string {
for i:=0;i<len(strs[0]);i++{//根据第一个字符串长度寻找最长公共前缀,在后面的判断中寻找长度是否越界
for j:=0;j<len(strs);j++{对每一个字符串的第i个字符进行比对
if i==len(strs[j])|| strs[j][i]!=strs[0][i]{//判断是有长度更短的字符串或者前缀不等的字符串,有的返回i之前的字符
return strs[0][:i]
}
}
}
return strs[0]
}
分治法,每次都将数据分成两部分进行对比,返回每个部分的最长前缀,再将前缀进行对比,最终返回共同前缀。
func longestCommonPrefix(strs []string) string {//分治法思想,将字符串平分为两组进行相互比较,比较出来的最长前缀再次进行比较,最终得出最长公共前缀
if len(strs) == 0 {
return ""
}
var cp func(int,int) string//定义递归函数,递归需要比较字符串的最长公共前缀
cp = func(start int,end int) string{//实现函数
if start==end{ //递归的终止条件为当范围内只有当前字符串,则返回当前字符串
return strs[start]
}
mid:=(start+end)/2 //分治,每次都将字符串分割称为两组
cpl,cpr:= cp(start,mid),cp(mid+1,end)//分成两组后再次调用递归函数,当范围内只有一个字符串时返回当前字符串,否则返回两边的最长公共前缀
minLength:=min(len(cpl), len(cpr))//返回的两边最短公共前缀,因为重叠需要最短重叠
for i:=0;i<minLength;i++{//判断两边的前缀的最长前缀
if cpl[i]!=cpr[i]{ //不等则返回最长前缀
return cpl[:i]
}
}
return cpl[:minLength]//全都相等则minlengh长的前缀
}
return cp(0,len(strs)-1)//递归入口
}
func min(x,y int) int{
if x<y {return x}
return y
}
二分法,通过二分法判断最长公共前缀的下标,每次寻找low、high之间的最长公共前缀,判断是否重合,当low>high时说明字符串最终位置已经找到,即[0:low-1]。
func longestCommonPrefix(strs []string) string {
if len(strs) == 0 {
return ""
}
//判断前缀是否相等函数,将mid值传进来,判断mid值前的前缀是否相等,返回bool
isequal:=func(lenth int) bool{
str0,count:=strs[0][:lenth],len(strs)
for i:=1;i<count;i++{
if strs[i][:lenth]!=str0{
return false
}
}
return true
}
minLenth:=len(strs[0])
for _,s :=range(strs){//计算最短字符串长度
if len(s)<minLenth{
minLenth=len(s)
}
}
low,high:=0,minLenth//则low high则为判断边界
for low<high{//当low>=high是,即当当前low值前不为最长前缀边界,则返回low之前的前缀,因为此时已经判断了前面的字符前缀为公共前缀
mid:=(high-low+1)/2+low
flag:=isequal(mid)
if flag{
low=mid
}else{
high=mid-1
}
}
return strs[0][:low]
}