package Misc; import java.util.*; public class RangeInSortedArray { public static void main(String[] args) { // Testcases assert Arrays.equals(sortedRange(new int[] {1, 2, 3, 3, 3, 4, 5}, 3), new int[] {2, 4}); assert Arrays.equals(sortedRange(new int[] {1, 2, 3, 3, 3, 4, 5}, 4), new int[] {5, 5}); assert Arrays.equals(sortedRange(new int[] {0, 1, 2}, 3), new int[] {-1, -1}); } // Get the 1st and last occurrence index of a number 'key' in a non-decreasing array 'nums' // Gives [-1, -1] in case element doesn't exist in array public static int[] sortedRange(int[] nums, int key) { int[] range = new int[] {-1, -1}; alteredBinSearchIter(nums, key, 0, nums.length - 1, range, true); alteredBinSearchIter(nums, key, 0, nums.length - 1, range, false); return range; } // Recursive altered binary search which searches for leftmost as well as rightmost occurrence of // 'key' public static void alteredBinSearch( int[] nums, int key, int left, int right, int[] range, boolean goLeft) { if (left > right) return; int mid = (left + right) / 2; if (nums[mid] > key) alteredBinSearch(nums, key, left, mid - 1, range, goLeft); else if (nums[mid] < key) alteredBinSearch(nums, key, mid + 1, right, range, goLeft); else { if (goLeft) { if (mid == 0 || nums[mid - 1] != key) range[0] = mid; else alteredBinSearch(nums, key, left, mid - 1, range, goLeft); } else { if (mid == nums.length - 1 || nums[mid + 1] != key) range[1] = mid; else alteredBinSearch(nums, key, mid + 1, right, range, goLeft); } } } // Iterative altered binary search which searches for leftmost as well as rightmost occurrence of // 'key' public static void alteredBinSearchIter( int[] nums, int key, int left, int right, int[] range, boolean goLeft) { while (left <= right) { int mid = (left + right) / 2; if (nums[mid] > key) right = mid - 1; else if (nums[mid] < key) left = mid + 1; else { if (goLeft) { if (mid == 0 || nums[mid - 1] != key) { range[0] = mid; return; } else right = mid - 1; } else { if (mid == nums.length - 1 || nums[mid + 1] != key) { range[1] = mid; return; } else left = mid + 1; } } } } public static int getCountLessThan(int[] nums, int key) { return getLessThan(nums, key, 0, nums.length - 1); } public static int getLessThan(int[] nums, int key, int left, int right) { int count = 0; while (left <= right) { int mid = (left + right) / 2; if (nums[mid] > key) right = mid - 1; else if (nums[mid] <= key) { count = mid + 1; // Atleast mid+1 elements exist which are <= key left = mid + 1; } } return count; } }