题目概述
- 算法说明
统计一个数字在升序数组中出现的次数。 - 测试用例
输入:
[1,2,3,3,3,3,4,5],3
输出:
4
解析&参考答案
- 解析
方法1: 扫描一般,记录出现的次数,时间复杂度过高;
方法2: 使用二分查找提高时间复杂度,分别查找最左边的的位置L和最右边的位置R,则结果为R-L+1。 - 参考答案
vim jz37.go
package main
import "fmt"
func GetNumberOfKV2(data []int, k int) int {
ret := 0
if data == nil || len(data) == 0 {
return 0
}
for _, v := range data {
if v == k {
ret++
}
}
return ret
}
func BinarySearchLeftK(data []int, k, start, end int) int {
if start > end {
return -1
}
mid := (start + end) / 2
if data[mid] > k {
return BinarySearchLeftK(data, k, start, mid-1)
} else if data[mid] < k {
return BinarySearchLeftK(data, k, mid+1, end)
} else {
// 找到k后,向左移动以便于确认左边相邻的是否为K
cur := mid
for i := mid - 1; i >= start; i-- {
if data[i] == k {
cur = i
} else {
break
}
}
return cur
}
}
func BinarySearchRightK(data []int, k, start, end int) int {
if start > end {
return -1
}
mid := (start + end) / 2
if data[mid] > k {
return BinarySearchRightK(data, k, start, mid-1)
} else if data[mid] < k {
return BinarySearchRightK(data, k, mid+1, end)
} else {
// 找到k后,向右移动以便于确认右边相邻的是否为K
cur := mid
for i := mid + 1; i <= end; i++ {
if data[i] == k {
cur = i
} else {
break
}
}
return cur
}
}
func GetNumberOfK(data []int, k int) int {
if data == nil || len(data) == 0 {
return 0
}
left := BinarySearchLeftK(data, k, 0, len(data)-1)
right := BinarySearchRightK(data, k, 0, len(data)-1)
if left != -1 && right != -1 {
return right - left + 1
} else {
return 0
}
}
func main() {
array := []int{1, 2, 3, 3, 3, 3, 4, 5}
k := 3
// result := GetNumberOfKV2(array, k)
result := GetNumberOfK(array, k)
fmt.Println(result)
}
注意事项
- to add
说明
- 当前使用 go1.15.8
- 参考 牛客网--剑指offer
标题中jzn(n为具体数字)代表牛客网剑指offer系列第n号题目,例如 jz01 代表牛客网剑指offer中01号题目。
注意!!!
- 笔者最近在学习 golang,因此趁机通过数据结构和算法来进一步熟悉下go语言
- 当前算法主要来源于剑指 offer,后续会进一步补充 LeetCode 上重要算法,以及一些经典算法
- 此处答案仅为参考,不一定是最优解,欢迎感兴趣的读者在评论区提供更优解