Google Interview Question for Software Engineers


Country: United States
Interview Type: Phone Interview




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

Can be solved by sorting the array, and then using two pointers to maintain a window and finding max length of the window.

1. Sort array - O(nlogn)
2. Maintain two pointers

start = 0, end = 0
ans = 0
while end < n:
     if arr[end+1] - arr[start] <= 1:
          end += 1
     else:
          start += 1
    ans = max(ans, end - start + 1)
    # also keep window track

- User123 July 12, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
2
of 2 vote

1. Sort the array
2. Go through each element - x, find the upper bound of (x+1). Compare and find the element with largest number of covered within 1.

O(nlogn) solution.

- peter tang June 13, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
1
of 3 vote

Can anyone please explain me the question itself ?
And from the example, how [-12.3,-13.3] is an answer when -13.3 is not even present.

- sonesh June 15, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

The range needs to be length 1. In this case it ends at -12.3, and starts 1.0 before that. The range includes the elements {-12.9, -12.5, -12.3}. If the range could be less than length 1 it might as well have ended at -12.9

- ZoeAcacia June 25, 2015 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

It means find two numbers so that
a) the difference between them is 1
b) most number of elements in the array lie between them.

To explain the answer [-12.3,-13.3], the difference between them is 1. Also -12.3, -12.5 and -12.9 lie between them. Similarly [-12,-13] also could've been an answer since it still would include those 3 numbers. But if we considered [-13,-14] then it will include only -13.7 so not a good answer.

- thewhatwhat July 03, 2015 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

I think I would need more details on the question. But, I think I understand the question enough. I unfortunately can't find a solution other than this quadratic one. But here's a solution in Python:

def find_max_range(data):
    sorted(data)
    max_range = [data[0], data[0] + 1]
    max_elems = 0
    lower, upper = data[0], data[0] + 1

    while upper <= data[-1]:
        tmp_count = 0
        for n in data:
            if n >= lower and n <= upper:
                tmp_count += 1
            if n > upper:
                break
        if tmp_count > max_elems:
            max_elems = tmp_count
            max_range[0] = lower
            max_range[1] = upper

        lower += 0.1
        upper += 0.1

    return max_range

- drincruz June 15, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

this solution is O(n log n + kn) where n is the amount of floats and k is the max amount of elements in a range of 1.

# given a range of floats, [2.3, 2.4, 5.5, 5.9, 9.0]
# find the range of size 1 with max number of elements

def find_range_with_max_elements(a):
    if not a:
        return
    a.sort()
    beg_i = 0
    num_elements = 1

    for i, elem in enumerate(a):
        walk = i+1

        while walk < len(a) and a[walk] - elem <= 1:
            walk += 1
        # get to one after the end, walk - 1 is last one in range
        if num_elements < walk - i:
            beg_i = i
            num_elements = walk - i
    return a[beg_i], a[beg_i]+1

print(find_range_with_max_elements([13.7, 14.5, 12.3, 12.5, 12.9]))

- brad June 16, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Here is an O(nlg(n)) algorithm:

1) Sort the array (which is O(nlg(n)) or O(n) if bounded).
2) For i = 1 to n, x=arr[i], binary search the array in the index range [i + 1, n] for the largest index j such that arr[j - 1] <= x + 1 < arr[j]. Save count = j - i as the number of floats in the interval [x, x + 1]. This is O(nlg(n)).
3) Keep a running total of the max count and return it. O(1)

Would be nice to have a solution that didn't require sorting.

- jarflores June 17, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Let’s see, what would be the brute force solution here? any range we choose will have one of the array elements in it, so we can select each element a[i], and check how many elements are in the range a[i]+1 and a[i]-1. If we do this for every element the solution time complexity is O(n^2) with O(1) extra space. Now how can we make this better? If we sort the array we will have all elements that are close next to each other. We can then select the first element in the sorted array and count how many elements are inside a[0],a[0]+1. Now when we get to an element that’s outside the range, we check if we remove a[0] were back to a range smaller than one. So we have to pointers, left and right, and we expand when the range is smaller than one and de-queue when the range is bigger than one. Now this solution is better because it only has O(nlgn) time complexity and still O(1) extra space if we do the sorting in-place. Now we should use the fact that the range has to be of size one, this implies we can somehow hash the values into buckets. If all the numbers were in range 0-m we could make an array of size m with counters for all the numbers with the same round/floor number. If the number’s range isn’t bound we can still do this with a hash table, with the round/floor number as the key. Now the problem is that doesn’t give us the optimal range, consider for example 0.1,0.7,0.8,1.1,1.5,1.6,1.7 neither bucket 0 or 1 contains the count of the maximum range [0.7,1.7] and we can’t find it only with the counts. What we can change is that we can hash the elements themselves and then check every pair of consecutive buckets. We can go through every bucket and check if bucket with (key+1) exists. Then we can check a pair of buckets again using sorting. If the numbers are randomly distributed checking a pair of buckets can be done in constant time, and we check O(n) buckets so the time complexity drops to O(n). To be more specific, if the average number of elements in a bucket is k, that is to say the load factor is k, the overall complexity would be O(n/k*klgk), so O(nlgk). It would be O(nlgn) worst case when all elements hash to two consecutive buckets. The tradeoff we made is that now we use O(n) extra space. We can make one more improvement if we knew that the range has to be quantized in some way, i.e. all maximum ranges are rounded somehow to d decimal digits then we can just use buckets to count the rounded numbers to their d decimal digits. For example, if the range returned has to be of the form [a.x, c.y], then 12.63 adds to the 12.6 bucket. Now we can get the maximum range using only the counters by iterating the buckets and checking if 10^d buckets exist and accumulating their counters. That wouldn’t require sorting and would reduce the time complexity to O(n*(10^d)) which is especially attractive if d is small. It would reduce the extra space complexity O(n/k). Note that in the case of randomly distributed numbers, k is a decreasing function of d.

- Omri.Bashari June 28, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 3 vote

* Sort the no
* Maintain sliding window(Dequeue)
* For each no, remove numbers from back until sum >= 1
Keep track of count

- krb June 09, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Algorithm isn't clear after the first step.

What kind of sliding window? Do you mean a window of width 1? Where does the dequeue come into play?
Remove the number from that back of what? Sum of what is >= 1?

What are you even trying to do?

- buntybittoo June 13, 2015 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

{
Pair<Float, Float> getRange(Float[] array) {
    if (array == null || array.length == 0) {
        return null;
    }
    if (array.length == 1) {
        return new Pair(array[0], array[0] + 1.0);
    }
    Arrays.sort(array, Collections.reverseOrder());
    int i = 0;
    int maxCount = 0;
    Pair<Float, Float> maxRange = null;
    while (i < array.length) {
        int count = 0;
        Pair<Float, Float> range = new Pair(array[i], array[i] - 1.0);
        for (int j = i; j < array.length; j++) {
            if (array[j] <= range.first && array[j] >= range.second) {
                count++;
            } else {
                break;
            }
        }
        if (count > maxCount) {
            maxCount = count;
            maxRange = range;
        }
        i++;
    }
    return maxRange;
}

}

- buntybittoo June 13, 2015 | Flag
Comment hidden because of low score. Click to expand.
-1
of 1 vote

Hash the values of all elements. Then go through, and for each element x, check if x + 1 or x -1 exist in the hashtable. If so, add such elements to a specific set. With all the sets, go through and check which set has the greatest number of elements. Return that set.

- SK June 10, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

As per this algo, the above example would produce an empty list as an o/p.the elements are not equi-distant and the start and end value of the range need not be the elements of the input array. (e.g for range [12.3,13.3], 13.3 does not exist in the input array)

- ns June 12, 2015 | Flag
Comment hidden because of low score. Click to expand.
-1
of 1 vote

We do not need to sort the whole array.
What about firstly distributing the array into groups of 1-intervals. For example 1-2,2-3... based on the integer part of the number (in java Map<Integer, List<Float>>).
Then sort these List<Float>s and for every single number, count it as : list.length + binarySearch on the group on the left and group on the right.

Complexity will be O(n) for dividing into the groups + O(k*logk) for sorting the groups + O(n*2*log k) for checking the neighbors.

- mbriskar June 11, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

I can only think of an exponential solution tothis problem
Algo:
- Get length of array (say 4)
- Generate all possible combinations of the ints between 0-3 (coz size 4)
avoiding same numbers in the combination so no 1231 or 11
So,
01
02
03
12
.
.
123
213
321
.
.
1230
0123
.
.
- Put these into a hashmap so these are the keys for which the values will be the resulting subtraction (maybe you can do that simultaneously as you generate the combinations to save some momory + runtime)
- Get the one with the max key length

- A June 14, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Even if you:

- sort the array (so, O(nlg(n)) or O(n) if they are bounded)
- for each value x in the array, loop through _every_ other value and count how many are in the interval [x, x + 1] (so O(n^2))
- return the x with the largest count

you have an O(n^2) solution that requires O(n) space. This is brute force and very not exponential.

- jarflores June 17, 2015 | Flag
Comment hidden because of low score. Click to expand.
-1
of 3 vote

For each element in the vector(after sorting), find the elements within range of 1.0.
We can use the number of elements in range for input[0] to compute the range for input[1] . This means that we do not process any element more than once( except the one at the boundaries between the ranges)
Complexity should be O(n log n) + approx O(n). Therefore O(nlogn)

float arr[]={-13.7, -14.5, -12.3, -12.5, -12.9};
	int size = sizeof(arr)/sizeof(arr[0]);
	std::vector<float> input(arr, arr+size );
	std::sort( input.begin(), input.end() );
	int maxElems = 0; //max elems in a range of 1.0
	int maxElemIndex = 0; //the index in the sorted array, of the beginning range
	int numCurElems = 0;
	for( int i=0,j=0; i<input.size()-maxElems; i++ ) {
		while( j<input.size() && input.at(j)-input.at(i) <= 1 ) {
			j++;numCurElems++;
		}

		if( numCurElems > maxElems ) {
			maxElemIndex = i;
			maxElems = numCurElems;
		}

		if( numCurElems + i <= j ) {
			numCurElems = 0;
		}
		j-- ;	//Start with the previous index to maintain the count	
	}

- Anonymous June 15, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

After sorting, For input[0], find the range. If the range, lets say x, is greater than 2, for input[1], we can use the range for input[0] and only process elements from input[x].
Complexity should be O(nlogn) + approx O(n) Therefore O(nlogn)

float arr[]={-13.7, -14.5, -12.3, -12.5, -12.9};
	int size = sizeof(arr)/sizeof(arr[0]);
	std::vector<float> input(arr, arr+size );
	std::sort( input.begin(), input.end() );
	int maxElems = 0;
	int maxElemIndex = 0;
	int numCurElems = 0;
	for( int i=0,j=0; i<input.size()-maxElems; i++ ) {
		while( j<input.size() && input.at(j)-input.at(i) <= 1 ) {
			j++;numCurElems++;
		}

		if( numCurElems > maxElems ) {
			maxElemIndex = i;
			maxElems = numCurElems;
		}

		if( numCurElems + i <= j ) {
			numCurElems = 0;
		}
		j--;		
	}

- CodeS June 15, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

After sorting, For input[0], find the range. If the range, lets say x, is greater than 2, for input[1], we can use the range for input[0] and only process elements from input[x].
Complexity should be O(nlogn) + approx O(n) Therefore O(nlogn)

float arr[]={-13.7, -14.5, -12.3, -12.5, -12.9};
	int size = sizeof(arr)/sizeof(arr[0]);
	std::vector<float> input(arr, arr+size );
	std::sort( input.begin(), input.end() );
	int maxElems = 0;
	int maxElemIndex = 0;
	int numCurElems = 0;
	for( int i=0,j=0; i<input.size()-maxElems; i++ ) {
		while( j<input.size() && input.at(j)-input.at(i) <= 1 ) {
			j++;numCurElems++;
		}

		if( numCurElems > maxElems ) {
			maxElemIndex = i;
			maxElems = numCurElems;
		}

		if( numCurElems + i <= j ) {
			numCurElems = 0;
		}
		j--;		
	}

- CodeS June 15, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

After sorting, For input[0], find the range. If the range, lets say x, is greater than 2, for input[1], we can use the range for input[0] and only process elements from input[x].
Complexity should be O(nlogn) + approx O(n) Therefore O(nlogn)

float arr[]={-13.7, -14.5, -12.3, -12.5, -12.9};
	int size = sizeof(arr)/sizeof(arr[0]);
	std::vector<float> input(arr, arr+size );
	std::sort( input.begin(), input.end() );
	int maxElems = 0;
	int maxElemIndex = 0;
	int numCurElems = 0;
	for( int i=0,j=0; i<input.size()-maxElems; i++ ) {
		while( j<input.size() && input.at(j)-input.at(i) <= 1 ) {
			j++;numCurElems++;
		}

		if( numCurElems > maxElems ) {
			maxElemIndex = i;
			maxElems = numCurElems;
		}

		if( numCurElems + i <= j ) {
			numCurElems = 0;
		}
		j--;		
	}

- scode June 15, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

Sort and then binary search, O(nlogn)

Double[] findMaxRange(Double[] a) {
  // step 1. sort the array
  Arrays.sort(a, Collections.reverseOrder());
  
  Double from = 0.0, to = 0.0;
  int max = 0;
  
  // step 2. for every element x, find the upper bound of x - 1
  // upper bound here means the largest number >= x - 1
  for (int i = 0; i < a.length; i++) {
    int j = upper(a, 0, a.length - 1, a[i] - 1);
    
    if (j - i + 1 > max) {
      from = a[i]; 
      to = a[i] - 1;
      max = j - i + 1;
    }
  }
  
  return new Double[]{from, to};
}

int upper(Double[] a, int lo, int hi, Double target) {      
  int mid = lo + (hi - lo) / 2;
  
  if (a[mid] >= target && (mid == a.length - 1 || a[mid + 1] < target)) {
    return mid;
  }
  
  if (a[mid] < target) {
    return upper(a, lo, mid - 1, target);
  } else {
    return upper(a, mid + 1, hi, target);
  }

}

- jean.timex July 30, 2015 | 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