Interview Question


Country: India




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

uses DP and more can be read on en.wikipedia.org/wiki/Partition_problem :

public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		int arr[] = new int[n];
		int K = 0;//sum of array

		for (int i = 0; i < n; i++) {
			arr[i] = in.nextInt();
			K = K + arr[i];
		}
		
		//algorithm starts here
		int M[] = new int[K + 1];
		M[0] = 1;
		for (int i = 0; i < n; i++) {
			for (int j = K - arr[i]; j >= 0; j--) {
				if (M[j] == 1)
					M[j + arr[i]] = 1;
			}
		}
		int mindiff = Integer.MAX_VALUE;
		for (int i = 1; i <= K; i++) {
			if (M[i] == 1) {
				int s1 = i;
				int s2 = K - s1;
				if (Math.abs(s2 - s1) < mindiff)
					mindiff = Math.abs(s2 - s1);
			}
		}
		System.out.println(mindiff);
	}

- salvo4u June 30, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

@solvo4u : take an array ={1,7,8,20,30,36}
acc to you , ans is 7
But the correct ans is {7,8,36} and {1,20,30} i.e.0

- Shobhit July 01, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

can be done using the greedy approach
eg-{1,2,3,4,5,6,7,8,9,10}
first sort
-strt from ending
-let A,B be two subset
-place the next element in the subset with minimum sum till that point
A - 10 B- 9
B- 8
A-7
A-6
B-5
B-4
A-3
A-2
B- 1

- codez July 01, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

@codz
That doesnt divide the 2 in equal halves....?

That solution will not work. Consider 1,5,6,20..
A-20
B-6
B-5
B-1

- Lokesh July 01, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

@Barney
try rechecking it i am getting the rite answer

- salvo4u July 01, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

My mistake . U r ryt .

- Shobhit July 01, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

try this , not tested properly

int[] a = { 1, 2, 3, 4, 5, 1 };
		int sm = 0;

		for (int i = 0; i < a.length; i++)
			sm += a[i];

		boolean[] dp = new boolean[sm + 1];
		dp[0] = true;

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

			for (int j = 0; j <= sm - a[i]; j++)
				if (dp[j])
					dp[j + a[i]] = true;
		}

		for (int i = sm / 2; i >= 0; i--)
			if (dp[i]) {
				System.out.printf("set 1:%d  set 2:%d\n", i, sm - i);
				break;

- Anonymous June 30, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

not tested 


int[] a = { 1, 2, 3, 4, 5, 1 };
		int sm = 0;
		for (int i = 0; i < a.length; i++)
			sm += a[i];

		boolean[] dp = new boolean[sm + 1];
		dp[0] = true;

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

			for (int j = 0; j <= sm - a[i]; j++)
				if (dp[j])
				dp[j + a[i]] = true;
		}

		for (int i = sm / 2; i >= 0; i--)
			if (dp[i]) {
			System.out.printf("set 1:%d  set 2:%d\n", i, sm - i);
			break;
			}

- Anonymous June 30, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

I think we can do this using backtracking. First make a note of no.of elements in the array(say 'n') and the sum of all those elements(say 'sum').

At the start of the backtracking function check if the no.of elements in temp array are equal to half of the elements in original array. If so, then calculate the sum of temp array and compare with original array sum.

Temp array sum having least difference with half of original array sum is one of the two half arrays we are looking for. The other half array will be with remaining elements of original array not included in first half array.

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

Agree with you .
Could you please explain the backtracking function as I'm having problems while writing it .

- Shobhit July 01, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Here is the backtracking function. I am printing only one half of the array. Hope you can print the other easily.

#include<stdio.h>

void halfArray(int a[], int b[], int c[], int pos, int start, int n, int sum, int currSum, int *minDiff)
{
 int diff, i;
 if(pos == n/2)
 {
  diff = ((sum/2) - currSum) > 0 ? (sum/2) - currSum : currSum - (sum/2);
  if(*minDiff > diff)
  {
   for(i=0; i < pos; i++)
   {
    c[i] = b[i];
   }
   *minDiff = diff;
  }
  return;
 }

 for( i = start; i < n; i++)
 {
  b[pos] = a[i];
  halfArray(a, b, c, pos+1, i+1, n, sum, currSum+a[i], minDiff);
 }
}

void main()
{
 int a[] = {1,2,3,4,5,6,7,8,9,10};
 int b[10]={0}, c[10]={0};
 int sum = 55; //given implicitly 
 int i;
 int *minDiff;
 clrscr();
 *minDiff = 1000;
 halfArray(a, b, c, 0, 0, 10, sum, 0, minDiff);
 printf("\n One half is :\n");
 for(i = 0; i < 5; i++)
  printf("%d ", c[i]);
 getch();

}

- Vamsy Krishna July 01, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Here is the backtracking approach:

#include <stdio.h>
#include <limits.h>
#include <stdlib.h>
 
 
void back(int *arr,int *sol,int N,int tillnow,int sumtillnow,int remainsum,int *finalsol)
{
        static int mindiff=INT_MAX;
        int i;
        if(tillnow==N/2)
        {
                if(abs(sumtillnow-remainsum)<mindiff)
                {
                        mindiff=abs(sumtillnow-remainsum);
                        for(i=0;i<N;i++)
                                finalsol[i]=sol[i];
                }
        }
        else
        {
                for(i=0;i<N;i++)
                {
                        if(!sol[i])
                        {
                                sol[i]=1;
                                back(arr,sol,N,tillnow+1,sumtillnow+arr[i],remainsum-arr[i],finalsol);
                                sol[i]=0;
                        }
                }
        }
}
 
int main()
{
        int arr[10]={1,2,3,4,5,6,7,8,9,10},sol[10]={0},finalsol[10],i,sum=0;
        for(i=0;i<10;i++)
                sum+=arr[i];
 
        back(arr,sol,10,0,0,sum,finalsol);
 
        for(i=0;i<10;i++)
        {
                if(finalsol[i])
                        printf("%d ",arr[i]);
        }
        printf("\n");
 
        for(i=0;i<10;i++)
        {
                if(!finalsol[i])
                        printf("%d ",arr[i]);
        }
}

- Aashish July 01, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

check it for array ={1,2,3,6}
your output is {3,6} and {1,2}
but the correct answer is {2,3} and {1,6}

- Shobhit July 01, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

@Barney, My program is working correctly for the input set given by you.
I request you to check it again. Can you provide the link where you tried it & it failed[like ideone]?
Here is the link where i have tried.
Please see: ideone.com/9c0A6
Note: Here i am not able to figure out why it is showing runtime error. The program is working perfectly under the ubuntu [gcc] platform without reporting any run-time error or segmentation fault[memory access violation exception].

- Aashish July 01, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

My mistake ..its working fine on Ubuntu ..

- Shobhit July 01, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Hope this works:


Assumptions are
All are positive elements
We have to split into 2 equal halves

Split it into 2 equal sets
Get the sum of each set
Set diff = |Sum(SetA) - Sum(SetB)|
While diff is > 1
Begin
-- Logic is try to reduce the difference between the two sets by exhanging 2 elements every time
DiferenceInDataToBeMoved = diff / 2
Find out the 2 elements one in SetA and another in SetB with diff <= DiferenceInDataToBeMoved
If 2 such elements are found
Exchange those 2 elemnts
Else
Return the 2 sets

Set diff = |Sum(SetA) - Sum(SetB)|
End

Return the 2 sets

- Swamy July 01, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

May be this will work
Find the sum of whole array =(s).
Now, we've to find an sub-array whose sum <= s/2 and min(s/2-sum) and must contain n elements.
One way is to create every possible sub-array(n elements) and find the min(s/2-sum) .

- Shobhit July 01, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Let us take an array which is sorted; eg:{1,2,3,6,8,9} - 4 elements
Te difference between the two subsets will be least when the elements are alternately put into the two different lists:
For example - first take 2 nos. - 1,2 =>put 1 in SetA and 2 in SetB [SetA{1} ; SetB{2}]
Then take the next two nos. - 3,6 => put 3 in SetB and 6 in SetA[SetA{1,6}, SetB{2,3}]
Then the next 2 - 8,9 => put 8 in SetA and 9 in SetB [SetA{1,6,8}; SetB{2,3,9}]

The logic is based on the fact that the difference will be least when the two nos. with least difference between them are put into different list. Sorting will automatically take care of this aspect. Now the reason behind alternating the insertions between the two sets is to keep the balance - if you inserted the smaller of the two nos. earlier in one set, compensate with a larger of the two nos. in the next iteration.

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

Sorry - I should have mentioned 6 elements here:
:{1,2,3,6,8,9} - 6 elements

- Saikat July 01, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

This is a tested code, it will work for all the cases, it is based on greedy algorithm where we start from index 1 and find the element which is nearest distance from it using O(n) time, then we put both these elements as used, now we use a par array of same size and maintain left and right index, now we see that if sumleft is less than sum right we put higher of the nearest neighbour in left part of partition that way trying to balance the sum of each half.

#include <stdio.h>
#include <stdlib.h>

int A[10] = {1,2,3,4,5,6,7,8,9,10};
bool used[10]={0};
int par[10]={0};

int mod(int n) {
  if ( n>=0) return n;
  else 
  return (-n);   
    
}

int findMinDiff(int A[], bool used[], int idx, int N) {
    int min = 1000; int minIndex = -1;
    for (int i =0; i <N; i++) {
        if(i==idx) continue;
        if(used[i]==1) continue;
        int diff =  mod(A[idx]-A[i]);
        if(diff < min){
            min = diff;
            minIndex = i;
        }   
    }
    printf("minimum distance neighbour for %d is %d with index %d and %d respectively\n",A[idx],A[minIndex],idx,minIndex);
    return (minIndex);
}
int sumL(int left){
    int sum=0;
    for (int j = 0; j <left; j++){
        sum=sum+par[j];
    }   
    printf("sum left for left=%d is \n",sum);
    return(sum);
}

int sumR(int right){
    int sum=0;
    for (int j = 9; j >right; j--){
        sum=sum+par[j];   
    }
    printf("sum right for right=%d is \n",sum);   
    return (sum);
}

int min(int a, int b) {
    if ( a < b) return a;
    else 
        return b;
     
}

int max(int a, int b) {
    if ( a > b) return a;
    else 
        return b;
}    

void partitionSum(){
    int M=10;
    int left=0; int right=M-1;
    
    for ( int i =0; i <M; i++ ){
        
         if(used[i]==1) continue;
         
         int j = findMinDiff(A,used,i,M);
         used[j]=1;  used[i]=1;
         if (sumL(left) <= sumR(right)) {
             par[left++] = max(A[i],A[j]);
             par[right--] =  min(A[i],A[j]); 
                       
         }    
         else {
             par[left++] = min(A[i],A[j]);
             par[right--] =  max(A[i],A[j]);     
         }
    }          
}
    
int main(){
 partitionSum();
 for(int i =0; i <10; i++)
     printf("%d ",par[i]);
    
  for(int k=0; k <10; k++)
      printf("%d ",used[k]);
 getchar();
 return 0;   
}

- ssaurabh July 01, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

To watch a beautiful solution to this problem through video lecture visit
youtu.be/ItF22I8f3Xs
The video explains the code beautifully

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

This comment has been deleted.

- Administrator June 30, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Partitioning is to be equal sized not arbitrary.

and, even if it is to be arbitrary your method will not work for:
A = [-1, 0 , 1]

- Anonymous June 30, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

@Anonymous . It is given that array contains only positive integers .

- Barney June 30, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Okay, even so, take A = [1, 5, 6, 10] Won't work !

He is forcing smallest and largest to be in different sets without any logic.

- Anonymous June 30, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

@Anonymous : You are right .
And it is also given that we've to divide the array in two equal halves .

- Shobhit July 01, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

See the solution of this problem at the following url
youtu.be/ItF22I8f3Xs
The video explains the code beautifully

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

1. Sort the array.
2. Pick odd indexed elements in the array for first set and even indexed elements for second set.

This solution will not work if arrays are not to be divided in two equal halves.

- skt June 30, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

take an example . a[]={1,2,3,6}
acc to u a1={1,3} and a2={2,6};
but the ans should be a1={1,6} and a2={2,3};

- Barney June 30, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

answer should be {6} {1,2,3}

- Anonymous June 30, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

i see..my earlier solution had flaw..

I think picking pairs of 1st and last(A1), 2nd and 2nd last(A2), 3rd and 3rd last(A1), 4th and 4th last(A2) .....till mid of array size.
logic: pair up max and min.

- skt June 30, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

@Anonymous : we've to divide the array in two equal halves .

- Shobhit July 01, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

@skt : take an array ={1,7,8,20,30,36}
acc to you : ans should be {1,8,36} and {7,20,30} or we can swap 8 and 20 .
But the correct ans is {7,8,36} and {1,20,30}

- Shobhit July 01, 2012 | Flag


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