Monday, July 24, 2017

Count number of occurrences (or frequency) in a sorted array


/*
    Problem: Given a sorted array arr[] and a number x, write a function that counts the occurrences of x in arr[]
    Solution :- Find the first occurrence and last occurrence of x in the array then the count last-first+1
    
 */
public class CountOccurences {
    public int countOccurrencesLinear(int arr[], int x) {
        int count = 0;
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] == x)
                count++;
        }
        return count;
    }

    public int countOccurrences(int[] nums, int x) {
        int first = first(nums, 0, nums.length - 1, x);
        if (first == -1)
            return 0;
        int last = last(nums, 0, nums.length - 1, x);
        return (last - first) + 1;
    }

    /*
        This is binary search with difference that even when we find matching element we have to keep
        going left till we find first occurrence 
     */
    public int first(int[] nums, int low, int high, int x) {
        if (low < high) {
            int mid = low + (high - low) / 2;
            //This is the differentiators if the num[mid]==x but the element before current is not
            //equal to mid then we found first occurance
            if (nums[mid] == x && nums[mid - 1] < x) {
                return mid;
            } else if (nums[mid] < x) {
                return first(nums, mid + 1, high, x);
            } else {
                return first(nums, low, mid - 1, x);
            }
        }
        return -1;
    }

    public int last(int[] nums, int low, int high, int x) {
        if (low < high) {
            int mid = low + (high - low) / 2;
            // If we found the element then check if the element after this is equal to current if not
            //that means we found the last occurance
            if (nums[mid] == x && nums[mid + 1] > x) {
                return mid;
            } else if (nums[mid] < x) {
                return first(nums, mid + 1, high, x);
            } else {
                return first(nums, low, mid - 1, x);
            }
        }
        return -1;
    }
}

No comments:

Post a Comment