Efficient way to count occurrences of a key in a sorted array

后端 未结 10 1507
粉色の甜心
粉色の甜心 2021-01-30 23:49

This was asked in on-site Microsoft interview.

Count the number of occurrences of a given key in an array.

I answered linear search because the elements may be s

相关标签:
10条回答
  • 2021-01-31 00:27

    For once, I will propose an implementation in C++.

    size_t count(std::vector<int> const& vec, int key)
    {
      auto p = std::equal_range(vec.begin(), vec.end(), key);
      return std::distance(p.first, p.second);
    }
    

    equal_range uses a binary search, the result is equivalent to:

    std::make_pair(std::lower_bound(vec.begin(), vec.end(), key),
                   std::upper_bound(vec.begin(), vec.end(), key));
    

    but the implementation should makes it slightly faster, even though all are in O(log N) (in terms of number of comparison).

    0 讨论(0)
  • 2021-01-31 00:29

    You can use recursive version of binary search

    int modifiedbinsearch_low(int* arr, int low, int high , int key)
    {   
        if(low==high) return high ; 
    
        int mid = low + (high-low) /2;
    
        if(key >  arr[mid] ) { modifiedbinsearch_low(arr,mid + 1 , high,key);  } 
        else  { modifiedbinsearch_low(arr,low,mid,key);  }  
    }
    int modifiedbinsearch_high(int* arr, int low, int high , int key)
    {   
        if(low==high) return high ; 
    
        int mid = low + (high-low) /2;
    
        if(key <  arr[mid] ) { modifiedbinsearch_high(arr,low,mid,key);  } 
        else  { modifiedbinsearch_high(arr,mid+1,high,key);  } 
    
    } 
    

    .

    int low = modifiedbinsearch_low( ...)
    
    int high = modifiedbinsearch_high( ...)
    

    (high - low) gives the number of keys

    0 讨论(0)
  • 2021-01-31 00:30

    package arrays;

    /* * Given a sorted array, find the number of times an element occured. * Binary search O(lgn) * */

    public class NumberOfN {

    static int bSearchLeft(int[] arr, int start, int end, int n){
    
        while(start < end){
    
            int mid = (start + end)>>1;
            if(arr[mid] < n){
                start = mid + 1;
            }else{
                end = mid;
            }
    
        }
    
        return end;
    }
    
    static int bSearchRight(int[] arr, int start, int end, int n){
    
        while(start < end){
    
            int mid = (start + end)>>1;
            if(arr[mid] <= n){
                start = mid + 1;
            }else{
                end = mid;
            }
    
        }
    
        return end;
    }
    
    /**
     * @param args
     */
    public static void main(String[] args) {
    
        int[] arr = new int[]{3,3,3,3};
        int n = 3;
        int indexLeft = bSearchLeft(arr, 0, arr.length, n);
        int indexRight = bSearchRight(arr, 0, arr.length, n);
        System.out.println(indexLeft + " " +indexRight);
        System.out.println("Number of occurences: " + (indexRight - indexLeft));
    }
    

    }

    0 讨论(0)
  • 2021-01-31 00:34

    We can solve this using Linear as well as Binary Search. But Linear Search will be O(n). Binary Search will give O(Logn). Hence it's better to use Binary search. The complete program is :

    public class Test4 {
    public static void main(String[] args) {
         int a[] = {1, 2, 2, 3, 3, 3, 6,6,6,6,6,66,7}; 
         int x =  6; 
    
             System.out.println(fix(a,x));
    }
    
    private static int fix(int[] a, int x) {
        int res = 0 ;
    
        for (int i = 0; i < a.length; i++) {
            int ch = a[i];
            if(x == ch) {res++ ;}
        }
        return res;
    }
    }
    

    There is another follow up question that's asked is : 1st and last occurence of a given number in a sorted array.

    class Occurence1 {
    
        public static void findFirstAndLast(int a[], int x) {
    
            int first = -1, last = -1;
            for (int i = 0; i < a.length; i++) {
                if (x == a[i]) {
                    if (first == -1) {
                        first = i;
                    }
                    // update last
                    last = i;
                } // if
    
            } // for                                                                           
            if (first != -1) {
                System.out.println("First Occurrence = " + first);
                System.out.println("Last Occurrence = " + last);
            } 
        }// end1
    
        public static void main(String[] args) {
            int arr[] = { 1, 2, 2, 2, 2, 3, 4, 7, 8, 8 };
            int x = 8;
            findFirstAndLast(arr, x);
        }
    }
    

    In Python :

    def findFirstAndLast(a, x):
        first = -1 ; last = -1
        for i in range(len(a)) :
            if(x == a[i]): 
                if(first == -1):first = i 
    
             # update last if the first contains oter value than -1    
            last = i
    
        if(first != -1):
            print("first => ",first)
            print("last =>", last)       
    
    
    a = [1, 2, 3,4, 5, 6, 7, 8, 1, 10, 10]
    x = 10
    findFirstAndLast(a, x)
    
    0 讨论(0)
提交回复
热议问题