2020-11-11:手寫代碼:如何得到有序數組中指定元素的個數?

福哥答案2020-11-11:golang

1.遍歷法。無代碼。
2.二分法。二分查找元素,而後二分查找左邊界,再查找右邊界,最後右邊界減去左邊界就是指定元素個數。這道題其實是以下三道題的綜合。數組

  1. 在一個有序數組中,找某個數是否存在 。
  2. 在一個有序數組中,找>=某個數最左側的位置 。
  3. 在一個有序數組中,找<=某個數最右側的位置 。

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

相關文章
相關標籤/搜索