Yahoo Interview Question for Software Engineer / Developers


Country: India
Interview Type: Written Test




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

a nice o(n) sln using o(n) extra space..good explanation too
www .geeksforgeeks.org/given-an-array-arr-find-the-maximum-j-i-such-that-arrj-arri/

- Amit July 21, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 3 votes

The solution you pointed out is not O(n). Though it's better than O(n^2) on average, but its worst case is still O(n^2).

- Anonymous July 22, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

A different solution can use tree, when add a right leaf, update j, and keep the max j - i that A[j] > A[i].
Complexity is less than O(n^)
sites.google.com/site/spaceofjameschen/home/tree/find-the-maximum-j---i-such-that-a-j-a-i

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

good! is the tree solution is O(n)?

- aaron.campbell July 24, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

The solution presented in the page is O(n) as it traverse the list in the worst case 4 times.

- Nelson Perez August 05, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Nice solution James using tree with average case O(nlogn). Worst case of constructing binary search tree is still O(n^2) though.

- Kiran T August 31, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

That was a great article. Here's a java version of the "efficient" version of that code:

public class IndicesMaxDiff {

	/*
	Yahoo!:
	Given an Array A[], find the maximum j - i such that A[j] > A[i]. 
    For example Input { 34,8,10,3,2,80,30,33,1} and Output 6 (j=7, i=1) 
    Time Complexity should be less then O(n^2)
    */
	
	/* For a given array arr[], returns the maximum j – i such that
    arr[j] > arr[i] */
	public static int maxIndexDiff(int[] arr)
	{
	    int maxDiff;
	    int i, j;
	    int n = arr.length;
	    
	    int[] LMin = new int[n];
	    int[] RMax = new int[n];
	 
	   /* Construct LMin[] such that LMin[i] stores the minimum value
	       from (arr[0], arr[1], ... arr[i]) */
	    LMin[0] = arr[0];
	    for (i = 1; i < n; ++i)
	        LMin[i] = Math.min(arr[i], LMin[i-1]);
	 
	    /* Construct RMax[] such that RMax[j] stores the maximum value
	       from (arr[j], arr[j+1], ..arr[n-1]) */
	    RMax[n-1] = arr[n-1];
	    for (j = n-2; j >= 0; --j)
	        RMax[j] = Math.max(arr[j], RMax[j+1]);
	 
	    /* Traverse both arrays from left to right to find optimum j - i
	        This process is similar to merge() of MergeSort */
	    i = 0;
	    j = 0;
	    maxDiff = -1;
	    while (j < n && i < n)
	    {
	        if (LMin[i] < RMax[j])
	        {
	            maxDiff = Math.max(maxDiff, j-i);
	            j = j + 1;
	        }
	        else
	            i = i+1;
	    }
	 
	    return maxDiff;
	}
 
	/* Driver program to test above functions */
	public static void main(String[] args) {
	    int[] arr = {9, 2, 3, 4, 5, 6, 7, 8, 18, 0};
	    int maxDiff = maxIndexDiff(arr);
	    System.out.println("Max diff for " + Arrays.toString(arr) + " is " + maxDiff + ".");
	    return;
	}

To whoever said that solution is O(n^2), I'd love to hear more of an explanation. I'm with nperez who points out that it's 4 passes that are at most n long which is still O(n)

- FredCycle March 27, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

The tree solution will be O(n^2) in the worst case because of the tree creation step, not while traversing it. For example, if all values are already in sorted and increasing order, your tree will break down into a linked list, as you are always inserting a right child. This will cause O(n) insertion for each of the N elements, or O(n^2).

- alex May 06, 2014 | Flag
Comment hidden because of low score. Click to expand.
1
of 1 vote

This one requires more logic chops than programming chops. If an array has a max gap of 1, we can save ourselves from iterating through every 1-gap solution by instead ruling out all non-1 solutions. I believe this is the only way to achieve a time complexity less than O(n^).

#!/usr/bin/ruby

# Given an Array A[], find the maximum j - i such that A[j] > A[i]. 
# For example Input {34,8,10,3,2,80,30,33,1} and Output 6 (j=7(33), i=1(34)) 
# Time Complexity should be less then O(n^2)

class Array
  def maxgap
    # If all elements are equal, return zero
    if self.count(self[0]) == self.size
      return 0
    end
    # If elements are sorted in descending order, return -1
    # which is the lowest return possible
    for i in 1...self.size do
      if self[i - 1] >= self[i] && i == self.size - 1
        return -1
      elsif self[i - 1] >= self[i] && i != self.size - 1
        next
      else
        break
      end
    end
    # Look for all possible results between max and 2
    (self.size - 1).downto(2) do |maxlength|
      for i in 0..self.size - maxlength - 1 do
        if self[i + maxlength] > self[i]
          return maxlength
        end
      end
    end
    # At this stage, all possible results besides 1 are
    # ruled out so 1 must be the correct answer.
    return 1
  end
end

puts [34,8,10,3,2,80,30,33,1].maxgap      
# => 6

- bad_sample July 23, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

You can apply the following logic as of binary search although the complexity is linear:
a. Find the middle element of the array
b. In order to find the max difference the indices should be as far as possible. So if arr[mid]>arr[low] find the index difference and if this difference is greater than the difference calculated so far then update this diff.
c. Similarly if arr[high]>arr[mid] find the difference as mentioned above.
d. Also find the difference of arr[high]-arr[low]. Suppose the starting and ending index of the sub-array are such that arr[high]>arr[low] then this would be the max difference
e. Also further check it for low+1,high and also for low,high-1
Below is the code:

#include <stdio.h>
#include <conio.h>

static int diff;
	
void findMaxDiff(int arr[],int low,int high)
{
	if(low==high)
		return;
	if(low+1==high)
	{
		if(arr[high]>arr[low])
		{
			int d=high-low;
			if(d>diff)
				diff=d;
		}
		return;
	}
	else
	{
		int mid=low+(high-low)/2;
		if(arr[mid]>arr[low])
		{
			int d=mid-low;
			if(d>diff)
				diff=d;
		}
		if(arr[high]>arr[mid])
		{
			int d=high-mid;
			if(d>diff)
				diff=d;
		}
		if(arr[high]>arr[low])
		{
			int d=high-low;
			if(d>diff)
				diff=d;
		}
		findMaxDiff(arr,low,high-1);
		findMaxDiff(arr,low+1,high);
	}
}
int main()
{
	int arr[]={65,23,12,43,33,13,67,78,54,21};
	int n=sizeof(arr)/sizeof(arr[0]);
	findMaxDiff(arr,0,n-1);
	printf(" The max j-i diff is %d ",diff);

}

- vgeek July 21, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

public static int run(int[] A){
int dinstanceMax = 0;
//The max cases :
// {j-i = length-1} > { j-i = length -2} > {j-i = length -3} >... > { j-i = -(length-1)}
// check A[j] > A[i] where any j - i > distanceMax
for(int j=A.length-1; j>=dinstanceMax; j--){
for(int i = 0; j - i>dinstanceMax ; i++){
//System.out.println("A["+j+"] : " + A[j]+" A["+i+"] : " + A[i]);
if(A[j] > A[i]){
System.out.println("A["+j+"] : " + A[j]+" A["+i+"] : " + A[i]);
dinstanceMax = j-i;
}
}
}
return dinstanceMax;

}

- Heesung July 21, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

public static int run(int[] A){
		int dinstanceMax = 0;
		//The max cases : 
		// {j-i = length-1} > { j-i = length -2} > {j-i = length -3} >... > { j-i = -(length-1)}
		// check A[j] > A[i] where any j - i > distanceMax
		for(int j=A.length-1; j>=dinstanceMax; j--){
			for(int i = 0; j - i>dinstanceMax ; i++){
				//System.out.println("A["+j+"] : " + A[j]+" A["+i+"] : " + A[i]);
				if(A[j] > A[i]){
					System.out.println("A["+j+"] : " + A[j]+" A["+i+"] : " + A[i]);
					dinstanceMax = j-i;
				}
			}
		}
		return dinstanceMax;
		
	}

- Heesung July 21, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Sorry for java code. The code doesn't uses the auxilary memory, no recursion and still does it in O(n). Please let me know if you find any fault in the code.


import java.util.Arrays;

public class MaxIGreaterJ {

public static int maxDiff(int arr[]){

int maxDiff = -1;
boolean breakCondition = false;

for(int i= 0 ; i< arr.length; i++){

int j=arr.length-1;

if(maxDiff > (j-i)) {
break;
}

while(i<j){
if( arr[i] < arr[j] && maxDiff < (j-i) && breakCondition ){
System.out.println("i= " + i +" j= " + j);
return (j-i);
}else if(arr[i] < arr[j] && maxDiff < (j-i)){
breakCondition = true;
maxDiff = j-i;
break;
}

j--;
}

}

return maxDiff;
}


public static boolean isAllAreDescending(int arr[]){
boolean swap =true;
int i=0;

while(i<1){
i++;
swap = false;
for(int j =0; j < arr.length-i;j++){
if(arr[j] < arr[j+1]){
swap =true;
break;
}

}


}

return !swap;
}

public static void maxDiffCaller(int arr[]){
if(isAllAreDescending(arr)){
System.out.println(" " + -1);
}else {
System.out.println(" " + maxDiff(arr));
}
}

public static void main(String args[]){

int arr1[] = new int[] {34, 8, 10, 3, 2, 80, 30, 33, 1};
maxDiffCaller(arr1);

int arr2[] = new int[] {9, 2, 3, 4, 5, 6, 7, 8, 18, 0};
maxDiffCaller(arr2);

int arr3[] = new int[] {6, 5, 4, 3, 2, 1};
maxDiffCaller(arr3);

}


}

- Guru July 22, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Sorry for java code. The code doesn't uses the auxilary memory, no recursion and still does it in O(n). Please let me know if you find any fault in the code.


import java.util.Arrays;

public class MaxIGreaterJ {

public static int maxDiff(int arr[]){

int maxDiff = -1;
boolean breakCondition = false;

for(int i= 0 ; i< arr.length; i++){

int j=arr.length-1;

if(maxDiff > (j-i)) {
break;
}

while(i<j){
if( arr[i] < arr[j] && maxDiff < (j-i) && breakCondition ){
System.out.println("i= " + i +" j= " + j);
return (j-i);
}else if(arr[i] < arr[j] && maxDiff < (j-i)){
breakCondition = true;
maxDiff = j-i;
break;
}

j--;
}

}

return maxDiff;
}


public static boolean isAllAreDescending(int arr[]){
boolean swap =true;
int i=0;

while(i<1){
i++;
swap = false;
for(int j =0; j < arr.length-i;j++){
if(arr[j] < arr[j+1]){
swap =true;
break;
}

}


}

return !swap;
}

public static void maxDiffCaller(int arr[]){
if(isAllAreDescending(arr)){
System.out.println(" " + -1);
}else {
System.out.println(" " + maxDiff(arr));
}
}

public static void main(String args[]){

int arr1[] = new int[] {34, 8, 10, 3, 2, 80, 30, 33, 1};
maxDiffCaller(arr1);

int arr2[] = new int[] {9, 2, 3, 4, 5, 6, 7, 8, 18, 0};
maxDiffCaller(arr2);

int arr3[] = new int[] {6, 5, 4, 3, 2, 1};
maxDiffCaller(arr3);

}


}

- Guru July 22, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

#include <iostream>
#define N 9

using namespace std;

int main()
{
	int A[N] = {34,8,10,3,2,80,30,33,1};
	int offset = 0;

	for(unsigned short int z=1; z<N-1; ++z)
	{
		unsigned short int y=0;
		while(y<z)
		{
			if(A[z]>A[y] && y<z)
			{
				offset = z - y;
				break;
			}
			++y;
		}
	}
	cout << "Offset : " << offset << endl;
    return 0;
}

- career July 23, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

How about this: we first sort the array according to the values A[i] into B, while keeping the index information so that if A[i] is the j-th smallest element in A, then B[j] = i. Then the question becomes: find two elements B[k] and B[l] in B so that: (1) k < l (2) B[l]-B[k] is maximized. This is just the one-time-max-profit-stock problem (see Introduction to Algorithms), which can be recast into a "maximum subarray" problem.

- Chih.Chiu.19 July 23, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

#include<stdio.h>

int max(int i,int j)
{
if(i>j)
return i;
else
return j;
}
int findMax(int A[],int i,int j)
{
if(A[j]>=A[i])
return j-i;
return max(findMax(A,i,j-1),findMax(A,i+1,j));
}
int main()
{
int a[10]={18,8,21,9,1,7,0,10,3,2};
printf("%d",findMax(a,0,9));
return 0;
}

- Akash & Johns July 27, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

#include<stdio.h>

int max(int i,int j)
{
if(i>j)
return i;
else
return j;
}
int findMax(int A[],int i,int j)
{
if(A[j]>=A[i])
return j-i;
return max(findMax(A,i,j-1),findMax(A,i+1,j));
}
int main()
{
int a[10]={18,8,21,9,1,7,0,10,3,2};
printf("%d",findMax(a,0,9));
return 0;
}

- Akash & Johns July 27, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

well to me it seems like that they are not asking for the max diff...hence this would be O(n)
{
int i=0, len=arr.length(); boolean found=false;
while(i<len && !found)
if(arr[i]<arr[len-i]
found=true
else
i++

return len-i-i;
}

- Dip July 28, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

The solution here is neat:
leetcode.com/2011/05/a-distance-maximizing-problem.html

- Xianshi December 13, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Please correct me if I am wrong.

public static void findMdiff(int a[])
    {
        if(a.length==0)
        {   System.out.println("Null array"); System.exit(0);}
        if(a.length==1)
            {   System.out.println("The max Diff is 0"); System.exit(0);}
        int min=0;int max=0;
         for(int i=1;i<a.length;i++)
        {
            if(a[i]<a[min])
            {
                min=i;
                
            }
            else if(a[i]>a[max])
            {
                max=i;
                
            }
            else
                continue;
        }
         System.out.println("The difference is great at "+max+" and "+min+" and the diff is : "+ (a[max]-a[min]));
    }

- wolfengineer February 22, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

function maximumApart(arr) {
  var i;
  var j;
  var result = [0, 0];
  for (i = 0; i < arr.length; i++) {
    if (arr.length - 1 - i < result[0] - result[1]) {
      break;
    }
    for (j = arr.length - 1; j > i; j--) {
      if (arr[j] > arr[i]) {
        if (j - i > result[0] - result[1]) {
          result[0] = j;
          result[1] = i;
        }
        break;
      }
    }
  }
  console.log(result);
  return result[0] - result[1];
}

var assert = require('assert');
assert.equal(maximumApart([34,8,10,3,2,80,30,33,1]), 6);

- realpeterz March 21, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Simple clean JavaScript solution

- realpeterz March 21, 2014 | Flag
Comment hidden because of low score. Click to expand.
-1
of 1 vote

#include<iostream>

using namespace std;

int main()
{
    
//   int a[] = {20,2,3,17,18};
//      int a[] = {145,146,47,10,9,8,7,6,100};
//    int a[] = {34, 8, 10, 3, 2, 80, 30, 33, 1};
    int a[] = {4,3,5,2,1,3,2,3};
    int i = 0, j = ( sizeof(a) / sizeof(a[0]) -1 ); 
    
    int max_diff = -1 ;
    
    int temp = j;
    
    int pos_max = -1;
    
    while( i <= j || pos_max == -1 )
    {
           if( a[j] > a[i]  )
           {
                 if ( max_diff < j - i)
                 {
                      max_diff = j - i;
                      
                      pos_max = j;
                      
                 }
                 
                 i++;
                 
                 j = temp;
           }
           
           else if (i == j)
           {
               i++;
               
               j=temp;
               
           }
           else
           {
               j--;
           }
           
    }
 
    cout<<"MAXIMUM DIFF : "<<max_diff;
}

- Amandeep July 20, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

O(n^2) for an array in decreasing order.

- viiids July 20, 2013 | Flag
Comment hidden because of low score. Click to expand.
-1
of 1 vote

Start one iterator at the start, keep track of min/ min position of this iterator.

Start one iterator at the end, keep track of max/ max position of this iterator.

Iterate from begin to end and end to begin with two iterators. When you notice max - min is greater than 1. Return the max position and min position. Fail if iterators cross middle O(N) speed O(1) space

- Some guy July 20, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

public int MaxDistance(int[] A)
{
if(A.length==0)
return -1;

int MaxLen=0;
int S=0; int E=A.length-1;
bool alternate=false;
while(S<=E)
{
if(A[E]>A[S])
{
MaxLen=Math.Max(MaxLen,E-S);
}
if(alternate)
S++;

else
E--;
alternate==true?false:true;
}
}

- perdition July 20, 2013 | Flag
Comment hidden because of low score. Click to expand.
-1
of 1 vote

Logic to search jthIndex and ithIndex for a[jthIndex]>a[ithIndex]
Note: ithIndex can be greater then jthIndex for some case and (j-i) could be best possible lesser -ve value
Ex:  9 8 7 6 5 4 3 1

Logic: Search for all possible couple for indexDiff where indexDiff is looping from (arraylength-1) to 1. Whenever I got a[jthIndex] > [index] for very first time... those ithIndex and jthIndex will be our ans.

Code:
void getMaxIndexDiffForCondition(int a[])
{
int ithIndex;
int jthIndex;

int flag;
int indexdiff;

flag = 0;
indexDiff = 0;

for(indexDiff = (a.length-1); indexDiff > 0; indexDiff++)
	{

	ithIndex = 0;
	jthIndex = indexDiff;

	while (jthIndex < a.length)
		{
		if(a[jthIndex] > a[ithIndex])
			{
			flag = 1;
			break;
			}
		else
			{
			ithIndex++;
			jthIndex++;
			}
		}
	if(flag==1)
		{
		break;
		}
	}

cout<<"best possible i and j for max (j-i) in such a way that a[j]>a[i] are:";
cout<<"index j="<<j;
cout<<"index i="<<i;
cout<<"element diff is"<<a[j]-a[i];
cout<<"index diff is"<<(j-1);

}

- PKT July 20, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

My answer suggestion: Please give comments

This idea will take extra space for index and original array. But time complexity will be less than square of n.
step 1: store the indices of the array and elements into 'index' and 'array'.
step 2: sort the elements using quick sort and store the indices of the element into the index array during the swap method. We will have the index with elements sorted.
step 3: use the following Find method to get the maximum element.
Idea of the Find method.
Start from end of the original array.  Start from beginning of the sorted array. If the element of the sorted array is less than original array, get the max separation by subtracting indices of the sorted array from present indices of the original array.(please see the find method)
Exit both for loops if the max separation is greater than the iterator of the first for loop.

namespace LargestSeperationBetweenAiLessAj
{
    class Program
    {
        public static float[] main = { 34, 8, 10, 3, 2, 80, 30, 33, 1 };
        public static int[] index;
        public static float[] orginal;
        static void Main(string[] args)
        {
            index=new int[main.Length];
            orginal = new float[main.Length];

            //sort the numbers.
            //store the index of the sorted numbers
            //use quicksort
            //go from last till the max <array.lenth-max
            for (int i = 0; i < main.Length; ++i)
            {
                index[i] = i;
                orginal[i] = main[i];
                Console.Write(index[i] + "=" + main[i] + "\t");
            }
            Console.WriteLine();
            Quicksort();
            for (int i = 0; i < main.Length; ++i)
                Console.Write(index[i] +"="+main[i] + "\t");

            Console.WriteLine("max=" + Find());
            Console.Read();

        }
        public static int Find()
        {
            int max = 0;
            for (int i = orginal.Length - 1; i >= max; --i)
            {
                 for (int j = 0; j <main.Length; ++j)
                    {
                        if (main[j] < orginal[i])
                        {
                            if (max < (i - index[j]))
                            {
                                max = i - index[j];
                            }
                        }
                        else
                        {
                            break;
                        }
                }
            }
            return max;
        }
        public static void Quicksort()
        {
            quicksort( 0, index.Length - 1);
        }

        // quicksort a[left] to a[right]
        private static void quicksort( int left, int right)
        {
            if (right <= left) return;
            int i = partition(left, right);
            quicksort( left, i - 1);
            quicksort( i + 1, right);
        }

        // partition a[left] to a[right], assumes left < right
        private static int partition(
        int left, int right)
        {
            int i = left - 1;
            int j = right;
            while (true)
            {
                while (less(main[++i], main[right]))      // find item on left to swap
                    ;                               // a[right] acts as sentinel
                while (less(main[right], main[--j]))      // find item on right to swap
                    if (j == left) break;           // don't go out-of-bounds
                if (i >= j) break;                  // check if pointers cross
                exchange(i, j);               // swap two elements into place
            }
            exchange(i, right);               // swap with partition element
            return i;
        }

        // is x < y ?
        private static bool less(float x, float y)
        {
            return (x < y);
        }

        // exchange a[i] and a[j]
        private static void exchange(int i, int j)
        {
            float swap = main[i];
            main[i] = main[j];
            main[j] = swap;
            int b = index[i];
            index[i] = index[j];
            index[j] = b;
        }
    }
}

- BVarghese July 20, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

I don't think you'll get less than sqrt of n if you are using quicksort.

- Some guy July 21, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

square of n not square root of n

- BVarghese July 21, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

sorry misread

- some guy July 21, 2013 | Flag
Comment hidden because of low score. Click to expand.
-2
of 2 vote

How it is differnt from longest increasing subsequnece and I think using patience sorting it can be done in O(nloglog n).
Basicallly longest such sequnce would be the answer.

- aka July 20, 2013 | 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