Count Occurrences of Element in Sorted Array in DSA Java - Time & Space Complexity
We want to know how long it takes to count how many times a number appears in a sorted list.
How does the time needed grow as the list gets bigger?
Analyze the time complexity of the following code snippet.
public int countOccurrences(int[] arr, int target) {
int first = findFirst(arr, target);
if (first == -1) return 0;
int last = findLast(arr, target);
return last - first + 1;
}
private int findFirst(int[] arr, int target) {
int low = 0, high = arr.length - 1;
int result = -1;
while (low <= high) {
int mid = low + (high - low) / 2;
if (arr[mid] == target) {
result = mid;
high = mid - 1;
} else if (arr[mid] < target) {
low = mid + 1;
} else {
high = mid - 1;
}
}
return result;
}
private int findLast(int[] arr, int target) {
int low = 0, high = arr.length - 1;
int result = -1;
while (low <= high) {
int mid = low + (high - low) / 2;
if (arr[mid] == target) {
result = mid;
low = mid + 1;
} else if (arr[mid] < target) {
low = mid + 1;
} else {
high = mid - 1;
}
}
return result;
}
This code finds the first and last positions of the target number using binary search, then calculates how many times it appears.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Binary search loops in
findFirstandfindLast. - How many times: Each binary search loop runs about log base 2 of n times, where n is the array size.
As the list gets bigger, the number of steps grows slowly because each step cuts the search space in half.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 6 steps (2 binary searches x ~3 steps each) |
| 100 | About 14 steps (2 x ~7 steps) |
| 1000 | About 20 steps (2 x ~10 steps) |
Pattern observation: Doubling the input size adds only a few more steps, showing slow growth.
Time Complexity: O(log n)
This means the time to count occurrences grows slowly as the list gets bigger, making it efficient for large lists.
[X] Wrong: "Counting occurrences requires checking every element one by one, so it must be slow (O(n))."
[OK] Correct: Because the list is sorted, we can use binary search to jump quickly to the first and last positions, avoiding checking every element.
Knowing how to use binary search to count occurrences shows you understand how to use sorting to speed up searching, a key skill in many coding challenges.
"What if the array was not sorted? How would the time complexity change?"
Practice
Solution
Step 1: Understand binary search efficiency
Binary search divides the search space in half each time, making it faster than checking every element.Step 2: Compare with linear search
Linear search checks each element one by one, which takes longer for large arrays.Final Answer:
It reduces the search time to logarithmic complexity -> Option BQuick Check:
Binary search = O(log n) time [OK]
- Thinking binary search sorts the array
- Confusing memory use with speed
- Assuming binary search works on unsorted arrays
target in a sorted array arr?Solution
Step 1: Check method return type and parameters
The method should return an integer count and accept an integer array and target integer as parameters.Step 2: Verify static and access modifiers
Static is common for utility methods; public allows access. The order of parameters matters for clarity.Final Answer:
public static int countOccurrences(int[] arr, int target) -> Option AQuick Check:
Correct signature returns int and takes (int[], int) [OK]
- Wrong parameter order
- Void return type instead of int
- Missing static keyword when needed
int[] arr = {1, 2, 2, 2, 3, 4, 5};
int target = 2;
int count = countOccurrences(arr, target);
System.out.println(count);
public static int countOccurrences(int[] arr, int target) {
int first = firstOccurrence(arr, target);
if (first == -1) return 0;
int last = lastOccurrence(arr, target);
return last - first + 1;
}
public static int firstOccurrence(int[] arr, int target) {
int low = 0, high = arr.length - 1, result = -1;
while (low <= high) {
int mid = low + (high - low) / 2;
if (arr[mid] == target) {
result = mid;
high = mid - 1;
} else if (arr[mid] < target) {
low = mid + 1;
} else {
high = mid - 1;
}
}
return result;
}
public static int lastOccurrence(int[] arr, int target) {
int low = 0, high = arr.length - 1, result = -1;
while (low <= high) {
int mid = low + (high - low) / 2;
if (arr[mid] == target) {
result = mid;
low = mid + 1;
} else if (arr[mid] < target) {
low = mid + 1;
} else {
high = mid - 1;
}
}
return result;
}Solution
Step 1: Find first occurrence of 2 in array
First occurrence is at index 1 (arr[1] = 2).Step 2: Find last occurrence of 2 in array
Last occurrence is at index 3 (arr[3] = 2).Step 3: Calculate count
Count = last - first + 1 = 3 - 1 + 1 = 3.Final Answer:
3 -> Option CQuick Check:
Occurrences of 2 = 3 [OK]
- Confusing first and last indices
- Off-by-one errors in count calculation
- Returning 0 when element exists
target in a sorted array arr:public static int countOccurrences(int[] arr, int target) {
int low = 0, high = arr.length - 1;
int count = 0;
while (low <= high) {
int mid = low + (high - low) / 2;
if (arr[mid] == target) {
count++;
low = mid + 1;
} else if (arr[mid] < target) {
low = mid + 1;
} else {
high = mid - 1;
}
}
return count;
}Solution
Step 1: Analyze counting logic in binary search
The code increments count only when arr[mid] == target and moves low to mid + 1, skipping elements before mid.Step 2: Understand missed occurrences
This approach counts occurrences only from the first found index forward, missing any before mid.Final Answer:
It counts only occurrences after the first found index -> Option AQuick Check:
Counting misses earlier duplicates [OK]
- Assuming count increments all occurrences
- Not updating low/high correctly
- Expecting binary search to count all duplicates directly
arr that may contain multiple occurrences of target, how can you efficiently count the occurrences if the array is very large and you want to minimize the number of comparisons?Solution
Step 1: Understand the problem constraints
Array is sorted and large, so linear scan is costly and sorting again is unnecessary.Step 2: Apply binary search twice
Use binary search to find the first occurrence index and last occurrence index of target efficiently.Step 3: Calculate count
Count = last occurrence index - first occurrence index + 1, minimizing comparisons.Final Answer:
Use two binary searches to find first and last occurrence, then subtract indices -> Option DQuick Check:
Two binary searches = efficient counting [OK]
- Using linear scan on large arrays
- Sorting already sorted array again
- Using extra memory unnecessarily
Ready to prove it?
Pass the test and this pattern moves unknown
