public class CountOccurrences { public static int countOccurrences(int[] arr, int x) { int first = firstOccurrence(arr, x); if (first == -1) return 0; int last = lastOccurrence(arr, x); return last - first + 1; } private static int firstOccurrence(int[] arr, int x) { int low = 0, high = arr.length - 1, result = -1; while (low <= high) { int mid = low + (high - low) / 2; if (arr[mid] == x) { result = mid; high = mid - 1; } else if (arr[mid] < x) { low = mid + 1; } else { high = mid - 1; } } return result; } private static int lastOccurrence(int[] arr, int x) { int low = 0, high = arr.length - 1, result = -1; while (low <= high) { int mid = low + (high - low) / 2; if (arr[mid] == x) { result = mid; low = mid + 1; } else if (arr[mid] < x) { low = mid + 1; } else { high = mid - 1; } } return result; } public static void main(String[] args) { int[] arr = {1, 2, 3, 3, 3, 4, 5}; System.out.println(countOccurrences(arr, 3)); } }
The code finds the first and last positions of 3 using binary search. The first occurrence is at index 2, the last at index 4. So, count = 4 - 2 + 1 = 3.
Finding first and last occurrences each takes O(log n) time. So total is O(log n) + O(log n) = O(log n).
public class CountOccurrencesBug { public static int countOccurrences(int[] arr, int x) { int first = firstOccurrence(arr, x); int last = lastOccurrence(arr, x); return last - first + 1; } private static int firstOccurrence(int[] arr, int x) { int low = 0, high = arr.length - 1, result = -1; while (low <= high) { int mid = low + (high - low) / 2; if (arr[mid] == x) { result = mid; high = mid - 1; } else if (arr[mid] < x) { low = mid + 1; } else { high = mid - 1; } } return result; } private static int lastOccurrence(int[] arr, int x) { int low = 0, high = arr.length - 1, result = -1; while (low <= high) { int mid = low + (high - low) / 2; if (arr[mid] == x) { result = mid; low = mid + 1; } else if (arr[mid] < x) { low = mid + 1; } else { high = mid - 1; } } return result; } public static void main(String[] args) { int[] arr = {1, 2, 3, 3, 3, 4, 5}; System.out.println(countOccurrences(arr, 7)); } }
When the element 7 is not found, firstOccurrence returns -1. The code does not check this before calculating last - first + 1, so last is also -1. The result is -1 - (-1) + 1 = 1.
public class CountOccurrencesEdges { public static int countOccurrences(int[] arr, int x) { int first = firstOccurrence(arr, x); if (first == -1) return 0; int last = lastOccurrence(arr, x); return last - first + 1; } private static int firstOccurrence(int[] arr, int x) { int low = 0, high = arr.length - 1, result = -1; while (low <= high) { int mid = low + (high - low) / 2; if (arr[mid] == x) { result = mid; high = mid - 1; } else if (arr[mid] < x) { low = mid + 1; } else { high = mid - 1; } } return result; } private static int lastOccurrence(int[] arr, int x) { int low = 0, high = arr.length - 1, result = -1; while (low <= high) { int mid = low + (high - low) / 2; if (arr[mid] == x) { result = mid; low = mid + 1; } else if (arr[mid] < x) { low = mid + 1; } else { high = mid - 1; } } return result; } public static void main(String[] args) { int[] arr = {2, 2, 2, 3, 4, 5, 6}; System.out.println(countOccurrences(arr, 2)); } }
The element 2 appears at indices 0, 1, and 2. So count = 2 - 0 + 1 = 3.
Binary search divides the search space in half each step, reducing the number of checks drastically compared to linear scan which checks every element.
