Count Occurrences in Sorted Array
Problem and examples
Given a sorted array of integers and a target number x, your task is to count how many times the number x appears in the array.
- If the number is not found in the array, return
0. - All elements in the array are sorted in non-decreasing order.
- You must use an efficient approach using binary search to find the count.
| Input Array | Key (x) | Count | Description |
|---|---|---|---|
| [1, 2, 2, 2, 3, 4] | 2 | 3 | 2 appears at indices 1, 2, 3 |
| [1, 1, 1, 1, 1] | 1 | 5 | All elements are the key |
| [5, 10, 10, 10, 20] | 10 | 3 | 10 appears three times in the middle |
| [1, 2, 3, 4, 5] | 6 | 0 | 6 is not present in the array |
| [1, 2, 3, 4, 5] | 0 | 0 | 0 is not present and is smaller than all elements |
| [2] | 2 | 1 | Single element match |
| [2] | 3 | 0 | Single element, but not a match |
| [] | 1 | 0 | Empty array, so count is 0 |
Explore Count Total Occurrences of an Element in a Sorted Array
Load an example or enter your own input. Use the player controls to follow each change.
Understanding the Problem
We are given a sorted array and a number x.
Our task is to count how many times x appears in that array.
Since the array is already sorted, we can make use of binary search to efficiently find the count, instead of scanning the entire array.
How We'll Solve It
We will solve this in three main steps:
- Use binary search to find the first occurrence of
x. - Use binary search again to find the last occurrence of
x. - If
xis found, compute the count aslastIndex - firstIndex + 1. Otherwise, return0.
Example: Let's Understand with an Example
Consider the array [2, 4, 4, 4, 6, 8] and x = 4.
- First occurrence of 4 is at index 1.
- Last occurrence of 4 is at index 3.
- So the count is
3 - 1 + 1 = 3.
What About Edge Cases?
-
Element appears only once:
Array =[1, 2, 3, 4, 5],x = 3. First and last occurrence both at index 2 → count = 1. -
Element doesn't exist:
Array =[1, 2, 4, 5],x = 3. Binary search returns -1 → count = 0. -
Element at the beginning:
Array =[2, 2, 3, 4],x = 2. First at 0, last at 1 → count = 2. -
Element at the end:
Array =[1, 2, 3, 4, 4],x = 4. First at 3, last at 4 → count = 2. -
Empty array:
Array =[], any value ofx→ count = 0.
Why Use Binary Search?
Because the array is sorted, binary search lets us locate the first and last occurrences in O(log n) time.
If we used a regular linear scan, it would take O(n) time, which is much slower for large arrays.
Finally
This solution is efficient and elegant. By simply applying binary search twice, we can handle all normal and edge cases with minimal extra code.
It’s especially beginner-friendly because the logic is easy to break down: find first, find last, subtract the indices — and you’re done!
- Use binary search to find the first occurrence of the key.
- Use binary search again to find the last occurrence of the key.
- If key is not found, return
0. - Otherwise, return
lastIndex - firstIndex + 1.
Implementation and efficiency
C implementation
#include <stdio.h>
int findFirst(int arr[], int n, int key) {
int start = 0, end = n - 1, res = -1;
while (start <= end) {
int mid = start + (end - start) / 2;
if (arr[mid] == key) {
res = mid;
end = mid - 1;
} else if (arr[mid] < key) {
start = mid + 1;
} else {
end = mid - 1;
}
}
return res;
}
int findLast(int arr[], int n, int key) {
int start = 0, end = n - 1, res = -1;
while (start <= end) {
int mid = start + (end - start) / 2;
if (arr[mid] == key) {
res = mid;
start = mid + 1;
} else if (arr[mid] < key) {
start = mid + 1;
} else {
end = mid - 1;
}
}
return res;
}
int countOccurrences(int arr[], int n, int key) {
int first = findFirst(arr, n, key);
int last = findLast(arr, n, key);
if (first == -1) return 0;
return last - first + 1;
}
int main() {
int arr[] = {1, 2, 2, 2, 3, 4};
int n = sizeof(arr)/sizeof(arr[0]);
int key = 2;
printf("Count of %d: %d\n", key, countOccurrences(arr, n, key));
return 0;
}C++ implementation
#include <iostream>
using namespace std;
int findFirst(int arr[], int n, int key) {
int start = 0, end = n - 1, res = -1;
while (start <= end) {
int mid = start + (end - start) / 2;
if (arr[mid] == key) {
res = mid;
end = mid - 1;
} else if (arr[mid] < key) {
start = mid + 1;
} else {
end = mid - 1;
}
}
return res;
}
int findLast(int arr[], int n, int key) {
int start = 0, end = n - 1, res = -1;
while (start <= end) {
int mid = start + (end - start) / 2;
if (arr[mid] == key) {
res = mid;
start = mid + 1;
} else if (arr[mid] < key) {
start = mid + 1;
} else {
end = mid - 1;
}
}
return res;
}
int countOccurrences(int arr[], int n, int key) {
int first = findFirst(arr, n, key);
int last = findLast(arr, n, key);
if (first == -1) return 0;
return last - first + 1;
}
int main() {
int arr[] = {1, 2, 2, 2, 3, 4};
int n = sizeof(arr)/sizeof(arr[0]);
int key = 2;
cout << "Count of " << key << ": " << countOccurrences(arr, n, key) << endl;
return 0;
}Python implementation
def count_occurrences(arr, key):
def find_first():
start, end = 0, len(arr) - 1
res = -1
while start <= end:
mid = (start + end) // 2
if arr[mid] == key:
res = mid
end = mid - 1
elif arr[mid] < key:
start = mid + 1
else:
end = mid - 1
return res
def find_last():
start, end = 0, len(arr) - 1
res = -1
while start <= end:
mid = (start + end) // 2
if arr[mid] == key:
res = mid
start = mid + 1
elif arr[mid] < key:
start = mid + 1
else:
end = mid - 1
return res
first = find_first()
last = find_last()
return last - first + 1 if first != -1 else 0
arr = [1, 2, 2, 2, 3, 4]
key = 2
print("Count of", key, ":", count_occurrences(arr, key))Java implementation
public class CountOccurrences {
public static int countOccurrences(int[] arr, int key) {
int first = findFirst(arr, key);
int last = findLast(arr, key);
if (first == -1 || last == -1) return 0;
return last - first + 1;
}
private static int findFirst(int[] arr, int key) {
int start = 0, end = arr.length - 1, res = -1;
while (start <= end) {
int mid = start + (end - start) / 2;
if (arr[mid] == key) {
res = mid;
end = mid - 1;
} else if (arr[mid] < key) {
start = mid + 1;
} else {
end = mid - 1;
}
}
return res;
}
private static int findLast(int[] arr, int key) {
int start = 0, end = arr.length - 1, res = -1;
while (start <= end) {
int mid = start + (end - start) / 2;
if (arr[mid] == key) {
res = mid;
start = mid + 1;
} else if (arr[mid] < key) {
start = mid + 1;
} else {
end = mid - 1;
}
}
return res;
}
public static void main(String[] args) {
int[] arr = {1, 2, 2, 2, 3, 4};
int key = 2;
System.out.println("Count of " + key + ": " + countOccurrences(arr, key));
}
}JavaScript implementation
function countOccurrences(arr, key) {
function findFirst() {
let start = 0, end = arr.length - 1, res = -1;
while (start <= end) {
const mid = Math.floor((start + end) / 2);
if (arr[mid] === key) {
res = mid;
end = mid - 1;
} else if (arr[mid] < key) {
start = mid + 1;
} else {
end = mid - 1;
}
}
return res;
}
function findLast() {
let start = 0, end = arr.length - 1, res = -1;
while (start <= end) {
const mid = Math.floor((start + end) / 2);
if (arr[mid] === key) {
res = mid;
start = mid + 1;
} else if (arr[mid] < key) {
start = mid + 1;
} else {
end = mid - 1;
}
}
return res;
}
const first = findFirst();
const last = findLast();
return first === -1 ? 0 : last - first + 1;
}
const arr = [1, 2, 2, 2, 3, 4];
const key = 2;
console.log("Count of", key, ":", countOccurrences(arr, key));Go implementation
package main
import (
"fmt"
)
func findFirst(arr []int, key int) int {
start, end, res := 0, len(arr)-1, -1
for start <= end {
mid := (start + end) / 2
if arr[mid] == key {
res = mid
end = mid - 1
} else if arr[mid] < key {
start = mid + 1
} else {
end = mid - 1
}
}
return res
}
func findLast(arr []int, key int) int {
start, end, res := 0, len(arr)-1, -1
for start <= end {
mid := (start + end) / 2
if arr[mid] == key {
res = mid
start = mid + 1
} else if arr[mid] < key {
start = mid + 1
} else {
end = mid - 1
}
}
return res
}
func countOccurrences(arr []int, key int) int {
first := findFirst(arr, key)
last := findLast(arr, key)
if first == -1 {
return 0
}
return last - first + 1
}
func main() {
arr := []int{1, 2, 2, 2, 3, 4}
key := 2
fmt.Printf("Count of %d: %d\n", key, countOccurrences(arr, key))
}Rust implementation
fn find_first(arr: &Vec<i32>, key: i32) -> i32 {
let (mut start, mut end) = (0, arr.len() - 1);
let mut res = -1;
while start <= end {
let mid = (start + end) / 2;
if arr[mid] == key {
res = mid as i32;
if mid == 0 { break; }
end = mid - 1;
} else if arr[mid] < key {
start = mid + 1;
} else {
if mid == 0 { break; }
end = mid - 1;
}
}
res
}
fn find_last(arr: &Vec<i32>, key: i32) -> i32 {
let (mut start, mut end) = (0, arr.len() - 1);
let mut res = -1;
while start <= end {
let mid = (start + end) / 2;
if arr[mid] == key {
res = mid as i32;
start = mid + 1;
} else if arr[mid] < key {
start = mid + 1;
} else {
if mid == 0 { break; }
end = mid - 1;
}
}
res
}
fn count_occurrences(arr: Vec<i32>, key: i32) -> i32 {
let first = find_first(&arr, key);
let last = find_last(&arr, key);
if first == -1 { 0 } else { last - first + 1 }
}
fn main() {
let arr = vec![1, 2, 2, 2, 3, 4];
let key = 2;
println!("Count of {}: {}", key, count_occurrences(arr, key));
}Kotlin implementation
fun countOccurrences(arr: IntArray, key: Int): Int {
fun findFirst(): Int {
var start = 0
var end = arr.size - 1
var res = -1
while (start <= end) {
val mid = (start + end) / 2
if (arr[mid] == key) {
res = mid
end = mid - 1
} else if (arr[mid] < key) {
start = mid + 1
} else {
end = mid - 1
}
}
return res
}
fun findLast(): Int {
var start = 0
var end = arr.size - 1
var res = -1
while (start <= end) {
val mid = (start + end) / 2
if (arr[mid] == key) {
res = mid
start = mid + 1
} else if (arr[mid] < key) {
start = mid + 1
} else {
end = mid - 1
}
}
return res
}
val first = findFirst()
val last = findLast()
return if (first == -1) 0 else last - first + 1
}
fun main() {
val arr = intArrayOf(1, 2, 2, 2, 3, 4)
val key = 2
println("Count of $key: ${countOccurrences(arr, key)}")
}Swift implementation
func countOccurrences(_ arr: [Int], _ key: Int) -> Int {
func findFirst() -> Int {
var start = 0, end = arr.count - 1, res = -1
while start <= end {
let mid = (start + end) / 2
if arr[mid] == key {
res = mid
end = mid - 1
} else if arr[mid] < key {
start = mid + 1
} else {
end = mid - 1
}
}
return res
}
func findLast() -> Int {
var start = 0, end = arr.count - 1, res = -1
while start <= end {
let mid = (start + end) / 2
if arr[mid] == key {
res = mid
start = mid + 1
} else if arr[mid] < key {
start = mid + 1
} else {
end = mid - 1
}
}
return res
}
let first = findFirst()
let last = findLast()
return first == -1 ? 0 : last - first + 1
}
let arr = [1, 2, 2, 2, 3, 4]
let key = 2
print("Count of \(key): \(countOccurrences(arr, key))")TypeScript implementation
function countOccurrences(arr: number[], key: number): number {
function findFirst(): number {
let start = 0, end = arr.length - 1, res = -1;
while (start <= end) {
const mid = Math.floor((start + end) / 2);
if (arr[mid] === key) {
res = mid;
end = mid - 1;
} else if (arr[mid] < key) {
start = mid + 1;
} else {
end = mid - 1;
}
}
return res;
}
function findLast(): number {
let start = 0, end = arr.length - 1, res = -1;
while (start <= end) {
const mid = Math.floor((start + end) / 2);
if (arr[mid] === key) {
res = mid;
start = mid + 1;
} else if (arr[mid] < key) {
start = mid + 1;
} else {
end = mid - 1;
}
}
return res;
}
const first = findFirst();
const last = findLast();
return first === -1 ? 0 : last - first + 1;
}
const arr: number[] = [1, 2, 2, 2, 3, 4];
const key: number = 2;
console.log(`Count of ${key}: ${countOccurrences(arr, key)}`);Time complexity
| Case | Time | Explanation |
|---|---|---|
| best case | O(1) | If both first and last occurrences are found on the first try. |
| average case | O(log n) | Binary search splits the array in half on each step, giving logarithmic performance. |
| worst case | O(log n) | Both first and last searches may take log n steps independently. |
Space complexity
O(1)
Only a few variables are used; no extra space is needed.