又是一篇水文,不说废话,上代码
func Test(strs []string) string {
// 将这个数组按照长度排序,减小循环次数
strs1 := strs[1:]
target := strs[0]
var pause bool
// var last string
for i := 0; i < len(strs[0]); i++ {
for _, str := range strs1 {
pause = strings.HasPrefix(str, target)
// fmt.Println(pause)
if !pause {
h := string(target[len(target)-1])
target = strings.TrimRight(target, h)
// fmt.Println(target, h)
}
}
}
return target
}
这是我原先的写法:基本原理就是以第一个字符串作为prefix,然后让strs除第一个元素之外元素组成的新数组,各个重新去进行hasPrefix的检验,如果有一个没通过,那就将prefix从末尾方向消去一个字母,一直到prefix合格为止。
但是其没过,为什么呢,leetcode提示我,strs := []string{"ab", "aa"},这个切片过不了关,然而电脑上是能过得,所以我也不知道怎么回事。
照例看一看其他人的写法
第一个:
func Test1(strs []string) string {
if len(strs) < 1 {
return ""
}
prefix := strs[0]
for _, k := range strs {
for strings.Index(k, prefix) != 0 {
if len(prefix) == 0 {
return ""
}
prefix = prefix[:len(prefix)-1]
}
}
return prefix
}
这个写法的思路其实和我一样的,只不过其用index这样的函数去替换了hasPrefix的函数,并用prefix[:len(prefix)-1]的方式去实现裁剪字符串,此外还加了一个预先的对空数组的检验。我这里说一下我的修改意见,其实也是对我自己方法的修改意见:首先,我会将strs切片除第一个元素之外的元素组成一个新的切片,毕竟第一个元素就是本身,没有检验的必要。其次我应该会将strs按照长度进行一个升序的排序,选最短的字符串元素作为prefix,当然这只是一点想法,可能会影响内存什么的。以上的方法和我一个思路,不错的。
第二种:
func LongestCommonPrefix(strs []string) string {
count := len(strs)
if count == 0 {
return ""
}
prefix := strs[0]
for i := 1; i < count; i++ {
prefix = lcp(prefix, strs[i])
if len(prefix) == 0 {
break
}
}
return prefix
}
// lcp 求两个字符串str1和str2的最长公共前缀
func lcp(str1, str2 string) string {
length := Min(len(str1), len(str2))
index := 0
for index < length && str1[index] == str2[index] {
index++
}
return str1[:index]
}
func Min(a, b int) int {
if a < b {
return a
}
return b
}
这位兄弟使用了多个函数,写的有点复杂,其实还是比较prefix,只不过是两个两个进行比较,我感觉他这个lcp函数可能写的有点复杂,因为要逐个字符进行比较
今日无力,不想再看哪,过了