福哥答案2020-11-11:golang
1.遍歷法。無代碼。
2.二分法。二分查找元素,而後二分查找左邊界,再查找右邊界,最後右邊界減去左邊界就是指定元素個數。這道題其實是以下三道題的綜合。數組
- 在一個有序數組中,找某個數是否存在 。
- 在一個有序數組中,找>=某個數最左側的位置 。
- 在一個有序數組中,找<=某個數最右側的位置 。
golang代碼以下:緩存
package main import "fmt" func main() { arr := []int{ 0, 1, 2, 3, 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 7, 8} v := 3 fmt.Println(v, "的個數是:", BSCount(arr, v)) } //二分法 func BSCount(arr []int, v int) int { L := 0 R := len(arr) - 1 M := -1 // L..R mid := -1 //找目標值而且縮小左邊界L和右邊界R的範圍 for L <= R { mid = L + (R-L)>>1 if arr[mid] == v { M = mid break } else if arr[mid] > v { R = mid - 1 } else { L = mid + 1 } } //沒找到目標值,直接返回 if M == -1 { return 0 } index := 0 LL := L //緩存原始左邊界 RR := R //緩存原始右邊界 //找左邊界 R = M //縮小範圍 for L <= R { mid = L + (R-L)>>1 if arr[mid] >= v { index = mid R = mid - 1 } else { L = mid + 1 } } LL = index //左邊界肯定下來了 R = RR //原始右邊界已經發生變化,須要恢復到之前的邊界 //找右邊界 L = M //縮小範圍 for L <= R { mid = L + (R-L)>>1 if arr[mid] <= v { index = mid L = mid + 1 } else { R = mid - 1 } } RR = index //右邊界肯定下來了 return RR - LL + 1 }
執行結果以下:
spa