-
Notifications
You must be signed in to change notification settings - Fork 4
/
solution.go
116 lines (106 loc) · 2.13 KB
/
solution.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package main
import (
"fmt"
"strings"
)
// Approach 1: Horizontal scanning
func longestCommonPrefix(strs []string) string {
// check if strs empty
if len(strs) == 0 {
return ""
}
// set the first str as prefix
prefix := strs[0]
// check if the following strs contain prefix
for _, v := range strs[1:] {
// trim the last char of prefix if the str does not contain prefix
for strings.Index(v, prefix) != 0 {
prefix = prefix[0 : len(prefix)-1]
}
}
return prefix
}
// Approach 2: Vertical scanning
func longestCommonPrefix2(strs []string) string {
// check if strs empty
if len(strs) == 0 {
return ""
}
for i := range strs[0] {
c := strs[0][i]
for j := range strs {
if i == len(strs[j]) || strs[j][i] != c {
return strs[0][0:i]
}
}
}
return strs[0]
}
//Approach 3: Divide and conquer
func longestCommonPrefix3(strs []string) string {
if len(strs) == 0 {
return ""
}
return dfs(strs, 0, len(strs)-1)
}
func dfs(strs []string, l int, r int) string {
if l == r {
return strs[l]
}
mid := (l + r) / 2
lcpLeft := dfs(strs, l, mid)
lcpRight := dfs(strs, mid+1, r)
return commonPrefix(lcpLeft, lcpRight)
}
func commonPrefix(left string, right string) string {
var min int
if len(left) > len(right) {
min = len(right)
} else {
min = len(left)
}
for i := 0; i < min; i++ {
if left[i] != right[i] {
return left[0:i]
}
}
return left[0:min]
}
//Approach 4: Binary search
func longestCommonPrefix4(strs []string) string {
if len(strs) == 0 {
return ""
}
minLen := 1<<32 - 1
for _, v := range strs {
if minLen > len(v) {
minLen = len(v)
}
}
low := 1
high := minLen
for low <= high {
middle := (low + high) / 2
if isCommonPrefix(strs, middle) {
low = middle + 1
} else {
low = middle - 1
}
}
return strs[0][0 : (low+high)/2]
}
func isCommonPrefix(strs []string, len int) bool {
str1 := strs[0][0:len]
for _, v := range strs {
if !strings.HasPrefix(v, str1) {
return false
}
}
return true
}
func main() {
strs := []string{"flower", "flow", "flo"}
fmt.Println(longestCommonPrefix2(strs))
fmt.Println(longestCommonPrefix3(strs))
fmt.Println(longestCommonPrefix4(strs))
}