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
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).
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
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));
}
}
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)