From 433f70e95dc31d1b6c49ea28c23887ae6952435b Mon Sep 17 00:00:00 2001 From: zhuyijun Date: Mon, 5 Apr 2021 14:26:54 +0800 Subject: [PATCH] =?UTF-8?q?'=E6=9C=80=E9=95=BF=E5=85=AC=E5=85=B1=E5=89=8D?= =?UTF-8?q?=E7=BC=80'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- leetcode/初级算法/字符串/最长公共前缀/main.go | 55 +++++++++++++++++++ .../字符串/最长公共前缀/二分查找/main.go | 48 ++++++++++++++++ .../初级算法/字符串/最长公共前缀/分治/main.go | 44 +++++++++++++++ .../字符串/最长公共前缀/横向扫描法/main.go | 47 ++++++++++++++++ .../字符串/最长公共前缀/纵向扫描法/main.go | 27 +++++++++ 5 files changed, 221 insertions(+) create mode 100644 leetcode/初级算法/字符串/最长公共前缀/main.go create mode 100644 leetcode/初级算法/字符串/最长公共前缀/二分查找/main.go create mode 100644 leetcode/初级算法/字符串/最长公共前缀/分治/main.go create mode 100644 leetcode/初级算法/字符串/最长公共前缀/横向扫描法/main.go create mode 100644 leetcode/初级算法/字符串/最长公共前缀/纵向扫描法/main.go diff --git a/leetcode/初级算法/字符串/最长公共前缀/main.go b/leetcode/初级算法/字符串/最长公共前缀/main.go new file mode 100644 index 0000000..6566a4b --- /dev/null +++ b/leetcode/初级算法/字符串/最长公共前缀/main.go @@ -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)) +} diff --git a/leetcode/初级算法/字符串/最长公共前缀/二分查找/main.go b/leetcode/初级算法/字符串/最长公共前缀/二分查找/main.go new file mode 100644 index 0000000..e04044e --- /dev/null +++ b/leetcode/初级算法/字符串/最长公共前缀/二分查找/main.go @@ -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)) +} diff --git a/leetcode/初级算法/字符串/最长公共前缀/分治/main.go b/leetcode/初级算法/字符串/最长公共前缀/分治/main.go new file mode 100644 index 0000000..9322c08 --- /dev/null +++ b/leetcode/初级算法/字符串/最长公共前缀/分治/main.go @@ -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)) +} diff --git a/leetcode/初级算法/字符串/最长公共前缀/横向扫描法/main.go b/leetcode/初级算法/字符串/最长公共前缀/横向扫描法/main.go new file mode 100644 index 0000000..fd17b93 --- /dev/null +++ b/leetcode/初级算法/字符串/最长公共前缀/横向扫描法/main.go @@ -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)) +} diff --git a/leetcode/初级算法/字符串/最长公共前缀/纵向扫描法/main.go b/leetcode/初级算法/字符串/最长公共前缀/纵向扫描法/main.go new file mode 100644 index 0000000..697e971 --- /dev/null +++ b/leetcode/初级算法/字符串/最长公共前缀/纵向扫描法/main.go @@ -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)) +}