Google Interview Question for Software Engineer / Developers






Comment hidden because of low score. Click to expand.
3
of 3 vote

Binary search the array, get the leftest element of k and the rightest element of k. Minus their positions.
Here is the c++ code:

#include <iostream>
using namespace std;

int left(int *array, int k, int start, int end)
{
    if (start > end)
    {
        return -1;
    }
    while (start < end)
    {
        int mid = start + (end - start) / 2;
        if (array[mid] == k)
        {
            end = mid;
        }
        else if (array[mid] > k)
        {
            end = mid - 1;
        }
        else
        {
            start = mid + 1;
        }
    }
    if (array[start] == k)
    {
        return start;
    }
    return -1;
}

int right(int *array, int k, int start, int end)
{
    if (start > end)
    {
        return -1;
    }
    if (start == end)
    {
        if (array[start] == k)
        {
            return start;
        }
        else
        {
            return -1;
        }
    }
    while (start < end - 1)
    {
        int mid = start + (end - start) / 2;
        if (array[mid] == k)
        {
            start = mid;
        }
        else if (array[mid] > k)
        {
            end = mid - 1;
        }
        else
        {
            start = mid + 1;
        }
    }
    if (array[end] == k)
    {
        return end;
    }
    if (array[start] == k)
    {
        return start;
    }
    return -1;
}

int main()
{
    int n, k;
    int array[1000];
    cin >> n >> k;
    for (int i = 0; i < n; ++i)
    {
        cin >> array[i];
    }
    int l = left(array, k, 0, n - 1);
    if (l == -1)
    {
        cout << "no such element" << endl;
        return 0;
    }
    int r = right(array, k, 0, n - 1);
    cout << r - l + 1 << endl;
    return 0;
}

- wenlei.zhouwl May 23, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

nice!

- gaoxiao October 23, 2013 | Flag
Comment hidden because of low score. Click to expand.
1
of 1 vote

Number of occurrences on n in array = upper_bound(arr, arr + sz, n) - lower_bound(arr, arr+ sz, n);

// assume sz = size of array.

- noob_coder May 01, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
1
of 1 vote

<pre lang="" line="1" title="CodeMonkey65921" class="run-this">import java.util.Arrays;

class CountTheDuplicate {

public int findOcurance(int[] arr, int key) {
if (arr == null || arr.length == 0) {
return 0;
}

// find the index of first element matching the key
int lowBound = findBound(arr, key);
if (lowBound == -1) {
return 0;
}

// find the index of last element matching the key
int highBound = findBound(arr, key, lowBound, arr.length - 1, false);

return highBound - lowBound + 1;
}

private int findBound(int[] arr, int key) {
return findBound(arr, key, 0, arr.length, true);
}

private int findBound(int[] arr, int key, int low, int high,
boolean forLowBound) {
while (low <= high) {
int mid = low + high >> 1;
int midVal = arr[mid];
if (midVal < key) {
low = mid + 1;
} else if (midVal > key) {
high = mid - 1;
} else {
/*
* Expanded equal case handling to directly pinpoint the
* range of equal elements by peeking into neighbor element
* (previous for low bound or next for high bound).
*
*/
if (forLowBound) {
if (mid == 0) {
return 0; // low bound found
}
if (arr[mid - 1] < key) {
return mid; // low bound found}
}
high = mid - 1;
} else {
if (mid == arr.length - 1) {
return arr.length - 1; // high bound found
}
if (arr[mid + 1] > key) {
return mid; // high bound found}
}
low = mid + 1;
}
}
}
return -1; // key not found.
}

public static void main(String[] args) {
int[] arr = new int[] { 2, 2, 4, 5, 5, 5, 5, 9, 11, 12, 12, 13, 14, 20,23, 24, 24, 26, 26, 28 };
CountTheDuplicate co = new CountTheDuplicate();
System.out.println(Arrays.toString(arr));
for (int key : new int[] { 1, 2, 5, 12, 14, 21, 28, 100 }) {
System.out.println(key + " occurs " + co.findOcurance(arr, key)
+ " times.");
}
}
}

</pre>

- Anonymous May 04, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

A typo in the only line method

private int findBound(int[] arr, int key) {
return findBound(arr, key, 0, arr.length, true);
}

Its fourth argument should be arr.length - 1 instead.

- Anonymous May 04, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Yes, I agree it would be faster ;)

- arkirakosyan May 05, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

You can easily do the same using a single method and two calls to the same method, I think that would be the preferred way :-)

- NirmalGeo May 06, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Of course. But either way has no impact on the complexity. The key point is how to modify binary search to fit this particular problem.

- Anonymous May 06, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

searching for a element in sorted array tkes O(logn)...and all occurrences of n should be in consecutive array elements...is that all...or am I missing something?

- Anonymous May 01, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

If all (or half of, or one third of, ...) the elements are identical, you algorithm would be O(n).

- Anonymous May 02, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

it can be done by using a variation of binary search. once the elemnt is found in O(log n) check the consecutive elements to the right and left till a non-match is found, and increment the counter.

- daisy898 May 01, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Checking consecutive elements to the right and left is not O(logn). Its worst case, when all elements are euqal to the target value, is O(n).

- Anonymous May 02, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

it can be done by using a variation of binary search. once the elemnt is found in O(log n) check the consecutive elements to the right and left till a non-match is found, and increment the counter.

- daisy898 May 01, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

int CountFreq (int *A, int value, int low, int high)
{
int mid;
if (high < low)
return 0;
mid = low + (high - low);
if (A[mid] > value)
return CountFreq (A, value, low, mid - 1);
else if (A[mid] < value)
return CountFreq (A, value, mid + 1, high);
else
return 1 + CountFreq (A, value, low, mid - 1) + CountFreq (A, value, mid + 1, high);
}

int main() {

int A[6] = { 1, 2, 3, 3, 3, 4};
int value = 3;

int count = 0;

printf("%d\n", CountFreq(A, value, 0, sizeof(A)/sizeof(int)-1));

return 0;

}

- x May 02, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

it should be mid = low + (high-low)/2;

- Dharmalingam Ganesan May 02, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

A good algo. It's simple and straightforward. But, it's not O(log n ) all the time. Its worst case, when all elements are equal to the target value, is O(n).

- Anonymous May 02, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

This is the same in cost as doing linear search to the left and right after finding the number, or worse as you are doing recursion.

- Anonymous May 03, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

1. Conduct binary search for an element witch equals to n and its previous element is equal to or less than n-1, taking the possibility that element being checked is the first element in the array into account.

2. Conduct binary search for an element witch equals to n and its next element is equal to or larger than n+1, taking the possibility that element being checked is the last element in the array into account.

3. From the result of step and step 2, figure out the occurance of n.

Since it costs two binary search regardless how many times n appears, it is an O(logn) solution.

- Anonymous May 02, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Actually can be modified as:

1. Check if the first element is equal to n. If yes, we have the low bound of n's, and go to step 3.

2. Conduct binary search for an element witch equals to n and its previous element is equal to or less than n-1. The result is the low bound of n's.

3.. Check if the last element is equal to n. If yes, we have the high bound of n's, and go to step 4.

4. Conduct binary search for an element witch equals to n and its next element is equal to or larger than n+1. The result is the high bound of n's.

5. n's occurance = high bound - low bound + 1.

- Anonymous May 02, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

<pre lang="" line="1" title="CodeMonkey30344" class="run-this">import java.util.Arrays;

public class CountTheDuplicate {

public int findOcurance(int[] arr, int key) {
if (arr == null || arr.length == 0) {
return 0;
}

int lowBound = findBound(arr, key, 0, arr.length - 1, true);
int highBound = findBound(arr, key, 0, arr.length - 1, false);
return lowBound == -1 ? 0 : highBound - lowBound + 1;
}

private int findBound(int[] arr, int key, int low, int high,
boolean forLowBound) {
while (low <= high) {
int mid = low + high >> 1;
int midVal = arr[mid];
if (midVal < key) {
low = mid + 1;
} else if (midVal > key) {
high = mid - 1;
} else {
if (forLowBound) {
if (mid == 0) {
return 0; // low bound found
}
if (arr[mid - 1] < key) {
return mid; // low bound found}
}
high = mid - 1;
} else {
if (mid == arr.length - 1) {
return arr.length - 1; // high bound found
}
if (arr[mid + 1] > key) {
return mid; // high bound found}
}
low = mid + 1;
}
}
}
return -1; // key not found.
}

public static void main(String[] args) {
int[] arr = new int[] { 2, 2, 4, 5, 5, 5, 5, 9, 11, 12, 12, 13, 14, 20,
23, 24, 24, 26, 26, 28 };
CountTheDuplicate ro = new CountTheDuplicate();
System.out.println(Arrays.toString(arr));
for (int key : new int[] { 1, 2, 5, 12, 14, 21, 28, 100 }) {
System.out.println(key + " occurs "
+ ro.findOcurance(arr, key) + " times.");
}
}
}</pre>

- Anonymous May 02, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

<pre lang="" line="1" title="CodeMonkey32379" class="run-this">In the code above, if the lowBound is -1, there is no need go any further. On the other hand, if lowBound is not -1, the search for highBound can be narrowed down to from lowBound to arr.length - 1. Given these, the findOcurance method can be improved as:


public int findOcurance(int[] arr, int key) {
if (arr == null || arr.length == 0) {
return 0;
}

int lowBound = findBound(arr, key, 0, arr.length - 1, true);
if (lowBound == -1) {
return 0;
}
return findBound(arr, key, lowBound, arr.length - 1, false) - lowBound + 1;
}
</pre>

- Anonymous May 03, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

<pre lang="" line="1" title="CodeMonkey8647" class="run-this">public static int FindOccurance(int[] arr, int n, int left, int right)
{
if(left > right) return 0;

int p = (left + right) / 2;
if (arr[p] > n)
return FindOccurance(arr, n, left, p - 1);
if(arr[p] < n)
return FindOccurance(arr, n, p + 1, right);

return 1 + ((p > left) ? FindOccurance(arr, n, left, p - 1) : 0) +((p < right) ? FindOccurance(arr, n, p + 1, right) : 0); }

int[] arr = { 1,2,3,4,4,4,4,4,5,6,7,8,9,10 };
Console.WriteLine(FindOccurance(arr, 4, 0, arr.Length - 1));
</pre><pre title="CodeMonkey8647" input="yes">
</pre>

- arkirakosyan May 03, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

An almost identical algo already posted yesterday by x. The algo is very compact and easy to understand, but the problem is it's not a O(logn) solution, which is required.

- Anonymous May 03, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

yes algo will run O(logn) if there is 1 ocurance the worst case is O(n). but I don't think it is posible to find O(logn) for the worst case

- arkirakosyan May 04, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

When talking an algorithm's complexity, its performance at the worst case rules.

- Anonymous May 04, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

yes algo will run O(logn) if there is 1 ocurance the worst case is O(n). but I don"t it is posible to find O(logn) for the worst case

- arkirakosyan May 04, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Yes, it's possible. Somebody already post the solution with both algorithm and complete Java code. It's O(logn) even when all elements are the same. It does the job through a variant binary search by expending equal condition handling to directly pinpoint low bound and high bound of the range of equal elements.

- Anonymous May 04, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Please code below:
simple algo work in O(log n) in all cases
Search element using binary search
keep start_index = end_index = searched_index (si = ei = i)
now search leftmost index using binary search (si = i)
again search rightmost index using binary search (ei = i)
print si & ei

- Rahul D May 06, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Code:

{
#include<stdio.h>

int a[] = {1,2,3,4,4,4,6,6,6,6,7};
int main()
{
int val = 4;
int si,ei;
int i = searchelem(val, 0 ,10);
si = ei = i;
while(i != -1)
{
si = i;
i = searchelem(val, 0, i-1);
}

i = ei;
while(i != -1)
{
ei = i;
i = searchelem(val, i+1, 10);
}
printf("From %d to %d find element = %d", si, ei, val);
}

int searchelem (int val, int low, int high)
{
int mid;

while(low <= high)
{
mid = (low+high)/2;
if(a[mid] == val)
return mid;
if(a[mid] > val)
high = mid-1;
else
low = mid+1;
}
return -1;
}
}

- Rahul D May 06, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Need to do 3 Binary searches.

1. Find the index for N. (at this stage you will have Low, N, High
2. Find Index of first between low-N and last N between N-High

- Sagar Udavat May 08, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

If estimating complexity is the main concern, it virtually takes two full range binary searches for the latter two are two sub-range searches, which combine to cover a full range from low to high.

- Anonymous May 09, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

takes O(logn)

- binary search for 'n' takes logn, say teh number 'x' found at index 'i'
- do a binary search between 'low' and 'i' for the number which is less than 'x'. you got the index 'i1'
- do a binary search between 'i' and 'high' for the number which is grater than 'x'. you got the index 'i2'
- so total occurances are i2-i1+1

- Vinod Patankar May 14, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

I get a 0(logn) method.

Maybe we can use a floating number array to store the integers.

To count a integer n, we only need two binary search for n-0.5 and n+0.5.
The binary search return the position of the smallest integet larger than n-0.5, which is the position of the first n, and the position of the smallest integer larger than n+0.5, which is also the position of the first smallest integet larget than n.
Substracting pos1 from pos2, we get the count.

This method appriciate the following conclusion: If a number is not in the sorted array, when the algorithm terminates, (right,left) or (-inf,left) or (right,inf) will be the range for the number.

- forandom June 02, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Do binary search for (n-1) and (n+1), the indexes are lower and upper bound of occurrences of n.
Which is O(nlogn)

For corner case, where all elements are same, check first and last elements, which is O(1).

- Algo_freak July 06, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

public class NumberOfOccurences {

	private void findNumOfOccurences(int[] arr, int element) {
		int low = 0;
		int high = arr.length - 1;
		int leftIndex = getLeftIndex(arr, element, low, high);
		System.out.println("Element : " + element);
		if (leftIndex == -1) {
			System.out.println("No such element exists");
			return;
		}
		System.out.println("Left Index : " + leftIndex);
		int rightIndex = getRightIndex(arr, element, leftIndex + 1, high);
		if (rightIndex == -1) {
			System.out.println("No of occurences : " + 1);
			return;
		}
		System.out.println("Right Index : " + rightIndex);
		System.out
				.println("No of occurences : " + (rightIndex - leftIndex + 1));
	}

	private int getLeftIndex(int[] arr, int element, int low, int high) {
		int pos = 0;
		if (high >= low) {
			int mid = (low + high) / 2;
			if (arr[mid] < element) {
				pos = getLeftIndex(arr, element, mid + 1, high);
				return pos;
			}
			if (arr[mid] > element) {
				pos = getLeftIndex(arr, element, low, mid - 1);
				return pos;
			}
			if (arr[mid] == element) {
				pos = getLeftIndex(arr, element, low, mid - 1);
				if (pos == -1) {
					pos = mid;
				}
				return pos;
			}
		}
		return -1;
	}

	private int getRightIndex(int[] arr, int element, int low, int high) {
		int pos = 0;
		if (high >= low) {
			int mid = (low + high) / 2;
			if (arr[mid] < element) {
				pos = getRightIndex(arr, element, mid + 1, high);
				return pos;
			}
			if (arr[mid] > element) {
				pos = getRightIndex(arr, element, low, mid - 1);
				return pos;
			}
			if (arr[mid] == element) {
				pos = getRightIndex(arr, element, mid + 1, high);
				if (pos == -1) {
					pos = mid;
				}
				return pos;
			}
		}
		return -1;
	}

	public static void main(String[] args) {
		NumberOfOccurences numOccurences = new NumberOfOccurences();
		int[] arr = { 1, 2, 3, 3, 3, 4, 8, 9, 10, 20 };
		numOccurences.findNumOfOccurences(arr, 4);
		System.out.println("---------------");
		numOccurences.findNumOfOccurences(arr, 3);
	}
}

Output
----------
Element : 4
Left Index : 5
No of occurences : 1
---------------
Element : 3
Left Index : 2
Right Index : 4
No of occurences : 3

- Abhishek January 16, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

public class countOcc
{
public static void main(String []args)
{
int []arr={1,1,1,2,2,2,2,2,2,2,2,3,3,4,5,5,6,6,7,8,9,10,10,10,10,11};
for( int i=0;i<12;i++)
	System.out.println("The occurance of "+i+" is: "+cntOcc(arr,i,0,arr.length)); 
}
public static int cntOcc(int []data,int key,int low,int high)
{
int temp,mid,lcount=0,rcount=0;
if(low>high) return 0;
mid=(low+high)/2;
if(data[mid]==key)
	{	
	if((mid-1)>0)
		lcount=cntOcc(data,key,low,mid-1);
	if((mid+1)<data.length)
		rcount=cntOcc(data,key,mid+1,high);
	return (lcount+rcount+1);
	}
else if(data[mid]>key)
	{
	return cntOcc(data,key,low,mid-1);
	}
else 	{
	return cntOcc(data,key,mid+1,high);
	}
}

}

- noobProg October 08, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

suppose that all the numbers are the same.
then the complexity is at least o(n), not o(log n)

- Anonymous November 21, 2012 | Flag Reply


Add a Comment
Name:

Writing Code? Surround your code with {{{ and }}} to preserve whitespace.

Books

is a comprehensive book on getting a job at a top tech company, while focuses on dev interviews and does this for PMs.

Learn More

Videos

CareerCup's interview videos give you a real-life look at technical interviews. In these unscripted videos, watch how other candidates handle tough questions and how the interviewer thinks about their performance.

Learn More

Resume Review

Most engineers make critical mistakes on their resumes -- we can fix your resume with our custom resume review service. And, we use fellow engineers as our resume reviewers, so you can be sure that we "get" what you're saying.

Learn More

Mock Interviews

Our Mock Interviews will be conducted "in character" just like a real interview, and can focus on whatever topics you want. All our interviewers have worked for Microsoft, Google or Amazon, you know you'll get a true-to-life experience.

Learn More