1. 问题
给定以非递减顺序排序的三个数组,找出这三个数组中的所有公共元素,例如下面三个数组 s1=[2,5,12,20,45,85], s2=[16,19,20,85,200],s3=[3,4,15,20,39,72,85,190] ,那么这三个数组的公共元素为 [20, 85]
2. 思路代码实现
2.1 遍历 + hash 表
- 先找出 3 个数组中第一个元素中的最大值,然后找出 3 个数组中最后一个元素中的最小值
- 依次遍历 3 个数组,将介于 (min, max) 之间的值存储在 map 中,其中数组元素作为 key,每出现一次 value 值加 1
- 统计 value 值 >= 3 的 key 就是我们要寻找的元素
package main
import "fmt"
func findCommonNumber(a []int, b []int, c []int) []int {
// 找出 3 个数组中第一个元素中的最大值
min := a[0]
if b[0] > min {
min = b[0]
}
if c[0] > min {
min = c[0]
}
// 找出 3 个数组中最后一个元素中的最小值
max := a[len(a)-1]
if b[len(b)-1] < max {
max = b[len(b)-1]
}
if c[len(c)-1] < max {
max = c[len(c)-1]
}
// 依次遍历 3 个数组,将介于 (min, max) 之间的值存储在 map 中,其中数组元素作为 key,
// 每出现一次 value 值加 1
d := make(map[int]int)
for i := 0; i < len(a); i++ {
if a[i] >= min && a[i] <= max {
d[a[i]] += 1
}
}
for i := 0; i < len(b); i++ {
if b[i] >= min && b[i] <= max {
d[b[i]] += 1
}
}
for i := 0; i < len(c); i++ {
if c[i] >= min && c[i] <= max {
d[c[i]] += 1
}
}
// 统计 value 值 >= 3 的 key 就是我们要寻找的元素
commonSlice := make([]int, 0)
for k, v := range d {
if v >= 3 {
commonSlice = append(commonSlice, k)
}
}
return commonSlice
}
func main() {
a1 := []int{2, 5, 12, 20, 45, 85}
a2 := []int{16, 19, 20, 85, 107}
a3 := []int{3, 4, 15, 20, 39, 72, 85, 110}
fmt.Println(findCommonNumber(a1, a2, a3))
}
2.2 仅遍历一次
i,j,k, 分别为数组的索引,如果 a[i] == b[j] == c[k] 那么这个元素就是公共元素,此时对 i,j,k,分别加 1,如果 a[i] < b[j],那么就对 i++, 如果 b[j] < c[k] 就对 j++,否则就对 k++。
package main
import "fmt"
func findCommonNumber(a []int, b []int, c []int) []int {
commonSlice := make([]int, 0)
for i, j, k := 0, 0, 0; i < len(a) && j < len(b) && k < len(c); {
if a[i] == b[j] && a[i] == c[k] {
commonSlice = append(commonSlice, a[i])
i++
j++
k++
} else if a[i] < b[j] {
// a[i] 不可能是公共元素
i++
} else if b[j] < c[k] {
// b[j] 不可能是公共元素
j++
} else {
k++
}
}
return commonSlice
}
func main() {
a1 := []int{2, 5, 12, 20, 45, 85}
a2 := []int{16, 19, 20, 85, 107}
a3 := []int{3, 4, 15, 20, 39, 72, 85, 110}
fmt.Println(findCommonNumber(a1, a2, a3))
}