'最长公共前缀'
This commit is contained in:
parent
95aa943b60
commit
433f70e95d
55
leetcode/初级算法/字符串/最长公共前缀/main.go
Normal file
55
leetcode/初级算法/字符串/最长公共前缀/main.go
Normal file
@ -0,0 +1,55 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
/**
|
||||
编写一个函数来查找字符串数组中的最长公共前缀。
|
||||
如果不存在公共前缀,返回空字符串""。
|
||||
|
||||
示例 1:
|
||||
输入:strs = ["flower","flow","flight"]
|
||||
输出:"fl"
|
||||
示例 2:
|
||||
|
||||
输入:strs = ["dog","racecar","car"]
|
||||
输出:""
|
||||
解释:输入不存在公共前缀。
|
||||
|
||||
提示:
|
||||
0 <= strs.length <= 200
|
||||
0 <= strs[i].length <= 200
|
||||
strs[i] 仅由小写英文字母组成
|
||||
|
||||
*/
|
||||
|
||||
func longestCommonPrefix(strs []string) string {
|
||||
if len(strs) == 0 {
|
||||
return ""
|
||||
}
|
||||
minlen := len(strs[0])
|
||||
//获取数组中最短的长度
|
||||
for _, str := range strs {
|
||||
if len(str) < minlen {
|
||||
minlen = len(str)
|
||||
}
|
||||
}
|
||||
var result bytes.Buffer
|
||||
|
||||
for i := 0; i < minlen; i++ {
|
||||
temp := strs[0][i]
|
||||
for _, str := range strs {
|
||||
if str[i] != temp {
|
||||
return result.String()
|
||||
}
|
||||
}
|
||||
result.WriteByte(strs[0][i])
|
||||
}
|
||||
return result.String()
|
||||
}
|
||||
func main() {
|
||||
var a =[]string{"abcadc","abcad"}
|
||||
fmt.Printf(longestCommonPrefix(a))
|
||||
}
|
48
leetcode/初级算法/字符串/最长公共前缀/二分查找/main.go
Normal file
48
leetcode/初级算法/字符串/最长公共前缀/二分查找/main.go
Normal file
@ -0,0 +1,48 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
/**
|
||||
最长公共前缀的长度不会超过字符串数组中的最短字符串的长度。
|
||||
用 minLength 表示字符串数组中的最短字符串的长度,则可以在
|
||||
[0,minLength] 的范围内通过二分查找得到最长公共前缀的长度。
|
||||
每次取查找范围的中间值 mid,判断每个字符串的长度为mid 的前缀是否相同,
|
||||
如果相同则最长公共前缀的长度一定大于或等于 mid,如果不相同则
|
||||
最长公共前缀的长度一定小于mid,通过上述方式将查找范围缩小一半,
|
||||
直到得到最长公共前缀的长度
|
||||
*/
|
||||
func longestCommonPrefix(strs []string) string {
|
||||
if len(strs) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
isCommonPrefix := func(length int) bool {
|
||||
str0, count := strs[0][:length], len(strs)
|
||||
for i := 1; i < count; i++ {
|
||||
if strs[i][:length] != str0 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
minLength := len(strs[0])
|
||||
for _, s := range strs {
|
||||
if len(s) < minLength {
|
||||
minLength = len(s)
|
||||
}
|
||||
}
|
||||
low, high := 0, minLength
|
||||
for low < high {
|
||||
mid := (high - low + 1) / 2 + low
|
||||
if isCommonPrefix(mid) {
|
||||
low = mid
|
||||
} else {
|
||||
high = mid - 1
|
||||
}
|
||||
}
|
||||
return strs[0][:low]
|
||||
}
|
||||
func main() {
|
||||
var a =[]string{"abcadc","abcad"}
|
||||
fmt.Printf(longestCommonPrefix(a))
|
||||
}
|
44
leetcode/初级算法/字符串/最长公共前缀/分治/main.go
Normal file
44
leetcode/初级算法/字符串/最长公共前缀/分治/main.go
Normal file
@ -0,0 +1,44 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
/**
|
||||
分治
|
||||
|
||||
以使用分治法得到字符串数组中的最长公共前缀。对于问题 LCP(Si...Sj),
|
||||
可以分解成两个子问题LCP(Si...Smind)与LCP(Smd+1...Sj),其中mid =(i+j)/2。
|
||||
对两个子问题分别求解,然后对两个子问题的解计算最长公共前缀,即为原问题的解。
|
||||
|
||||
*/
|
||||
func longestCommonPrefix(strs []string) string {
|
||||
if len(strs) == 0 {
|
||||
return ""
|
||||
}
|
||||
var lcp func(int, int) string
|
||||
lcp = func(start, end int) string {
|
||||
if start == end {
|
||||
return strs[start]
|
||||
}
|
||||
mid := (start + end) / 2
|
||||
lcpLeft, lcpRight := lcp(start, mid), lcp(mid + 1, end)
|
||||
minLength := min(len(lcpLeft), len(lcpRight))
|
||||
for i := 0; i < minLength; i++ {
|
||||
if lcpLeft[i] != lcpRight[i] {
|
||||
return lcpLeft[:i]
|
||||
}
|
||||
}
|
||||
return lcpLeft[:minLength]
|
||||
}
|
||||
return lcp(0, len(strs)-1)
|
||||
}
|
||||
|
||||
func min(x, y int) int {
|
||||
if x < y {
|
||||
return x
|
||||
}
|
||||
return y
|
||||
}
|
||||
|
||||
func main() {
|
||||
var a =[]string{"abcadc","abcad"}
|
||||
fmt.Printf(longestCommonPrefix(a))
|
||||
}
|
47
leetcode/初级算法/字符串/最长公共前缀/横向扫描法/main.go
Normal file
47
leetcode/初级算法/字符串/最长公共前缀/横向扫描法/main.go
Normal file
@ -0,0 +1,47 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
/**
|
||||
|
||||
lcp(S1~Sn) = lcp(lcp(lcp(S1,S2),S3),....Sn)
|
||||
字符串数组两个字符串两个字符串进行求公共最长前缀,依次向右移动,直至移动到最后,返回最长子串
|
||||
|
||||
如果在尚未遍历完所有的字符串时,最长公共前缀已经是空串,则最长公共前缀一定是空串,因此不需要继续遍历剩下的字符串,直接返回空串即可。
|
||||
|
||||
*/
|
||||
func longestCommonPrefix(strs []string) string {
|
||||
//如果strs数组为空这返回""
|
||||
if len(strs) == 0 {
|
||||
return ""
|
||||
}
|
||||
prefix := strs[0]
|
||||
count := len(strs)
|
||||
for i := 1; i < count; i++ {
|
||||
prefix = lcp(prefix, strs[i])
|
||||
if len(prefix) == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return prefix
|
||||
}
|
||||
//两个字符串公共子串
|
||||
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(x, y int) int {
|
||||
if x < y {
|
||||
return x
|
||||
}
|
||||
return y
|
||||
}
|
||||
|
||||
func main() {
|
||||
var a =[]string{"abcadc","abcad"}
|
||||
fmt.Printf(longestCommonPrefix(a))
|
||||
}
|
27
leetcode/初级算法/字符串/最长公共前缀/纵向扫描法/main.go
Normal file
27
leetcode/初级算法/字符串/最长公共前缀/纵向扫描法/main.go
Normal file
@ -0,0 +1,27 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
/**
|
||||
方法一是横向扫描,依次遍历每个字符串,更新最长公共前缀。另一种方法是纵向扫描。
|
||||
纵向扫描时,从前往后遍历所有字符串的每一列,比较相同列上的字符是否相同,
|
||||
如果相同则继续对下一列进行比较,如果不相同则当前列不再属于公共前缀,
|
||||
当前列之前的部分为最长公共前缀。
|
||||
|
||||
*/
|
||||
func longestCommonPrefix(strs []string) string {
|
||||
if len(strs) == 0 {
|
||||
return ""
|
||||
}
|
||||
for i := 0; i < len(strs[0]); i++ {
|
||||
for j := 1; j < len(strs); j++ {
|
||||
if i == len(strs[j]) || strs[j][i] != strs[0][i] {
|
||||
return strs[0][:i]
|
||||
}
|
||||
}
|
||||
}
|
||||
return strs[0]
|
||||
}
|
||||
func main() {
|
||||
var a =[]string{"abcadc","abcad"}
|
||||
fmt.Printf(longestCommonPrefix(a))
|
||||
}
|
Loading…
Reference in New Issue
Block a user