Facebook Interview Question for Software Engineer / Developers


Country: United States
Interview Type: Phone Interview




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

we can take two pointers and store the occurance count and move left to right and swapping at any occurance of more than M with the next difference number.. this will leave same digits in the end .. so you will need to move from right to left and refill them.. will have no solution if a digit occurs more than N - (N/M) times in the pattern

- kkr.ashish January 22, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

I agree here. And this solution would be O(n^2).

- javierturek January 22, 2014 | Flag
Comment hidden because of low score. Click to expand.
-1
of 1 vote

For second part in which similar digits remains in the end, we can continue like circular array.
I mean end part of array for similar digits can be replaced with digits in initial part of array.

- SK January 22, 2014 | Flag
Comment hidden because of low score. Click to expand.
-1
of 1 vote

Can you explain to me how you arrived at the conclusion: "will have no solution if a digit occurs more than n - (n/m)" ..

let's say , m = 2 , n = 6 , then according the above logic we can't have a number repeated more than 3 i.e. ( 6 - 6/2) = 3

counter example:

111122
112112

- Anonymous January 24, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

sorry i gave an approx for the limit the right limit is N- (N/(M +1))
the results comes from if you have N objects then the min number of separators required is N/(M+1)

- kkr.ashish January 24, 2014 | Flag
Comment hidden because of low score. Click to expand.
1
of 1 vote

Yes, max repeat characters should be N-(N/M+1) = (N)* (M / (M+1))
So if repeated characters are greater than N * M / (M+1), then there will be no solution.

- SK January 24, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Can someone explain this solution a bit more in detail? Where does this two pointers point to and what is the criteria to select which positions to swap?

- Anonymous January 25, 2014 | Flag
Comment hidden because of low score. Click to expand.
2
of 2 votes

That's a good idea.

To improve run-time complexity (at the expense of space complexity), we can create a stack which stores for each consecutive appearance of an element - a point (element,consecutive_appearance). For instance, if the input is 2,1,1,1,3,4,4,4,5 - the stack would look like: {(2,1),(1,3),(3,1),(4,3),(5,1)}. This can be done in linear time.

The way the stack was built we know that it does not have any two consecutive elements whose integer values are the same. This means that when we extract an element from the stack the only thing we need to do in order to find an integer which differs from it is just look at the head of the stack.

private static class Occurence<T> {
		private T element;
		private int count;
		
		public Occurence(T element, int count){
			this.element = element;
			this.count = count;
		}
		public boolean isPositiveCount(){return count>0;}
		public void increment(){count++;}
		public void decrement(){count--;}
		public void reduceCount(int k){count-=k;}
		public void increaseCount(int k){count+=k;}
		public T getElement(){return element;}
		public int getCount(){return count;}
	}
	
	private static <T> Stack<Occurence<T>> buildCountStack(T[] arr){
		if (arr==null){return null;}
		
		Stack<Occurence<T>> stack = new Stack<Occurence<T>>();
		for (int i=0;i<arr.length;i++){
			if ((!stack.isEmpty()) && (stack.peek().getElement().equals(arr[i]))){
				stack.peek().increment();
			}
			else {
				stack.push(new Occurence<T>(arr[i],1));
			}
		}
		
		return stack;
	}
	
	private static <T> Stack<Occurence<T>> splitOccurences(Stack<Occurence<T>> stack, int m){
		if ((stack==null) || (stack.isEmpty()) || (m<1)){return stack;}
		
		Stack<Occurence<T>> res = new Stack<Occurence<T>>();
		Occurence<T> cur = stack.pop();
		while (!stack.isEmpty()){
			if (cur.getCount()>m){
				res.push(new Occurence<T>(cur.getElement(),m));
				cur.reduceCount(m);
				res.push(new Occurence<T>(stack.peek().getElement(),1));
				stack.peek().decrement();
				if (!stack.peek().isPositiveCount()){
					stack.pop();
					if ((!stack.isEmpty()) && (stack.peek().getElement().equals(cur.getElement()))){
						cur.increaseCount(stack.pop().getCount());
					}
				}
			}
			else {
				res.push(cur);
				cur = stack.pop();
			}
		}
		res.push(cur);
		
		return res;
	}
	
	public static <T> boolean removeConsecutives(T[] arr,int m){
		if (m<1){return false;}
		
		Stack<Occurence<T>> stack = splitOccurences(splitOccurences(buildCountStack(arr),m),m);
		if ((stack==null) || (stack.isEmpty()) || (stack.peek().getCount()>m)){return false;}
		int i=0;
		while ((!stack.isEmpty()) && (i<arr.length)){
			Occurence<T> cur = stack.pop();
			for (int j=0;(j<cur.getCount()) && (i<arr.length);j++){arr[i++]=cur.getElement();}
		}
		
		return true;
	}

Complexity: O(n) worst-case run-time complexity and O(n) space complexity.

- IvgenyNovo January 26, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

I don't think I understand your approach very well. Wouldn't your algorithm fail for the case 4,1,1,1,4,1,1,1?

- Anonymous January 26, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

assuming M=2..
41141111 => 1st pass (L->R)
41111411 -> 11411411 => 2nd pass(R->L) so it dint fail

- kkr.ashish January 26, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Then 14114111, or 14111411. I don't see a way to make a linear algorithm work well.

- Anonymous January 26, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

11411411 is the solution and yes the linear algorithm works.. you haven't understood the algorithm

- kkr.ashish January 26, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

case1: 14114111 -> 14114111-> 14111411-> 11411411
case2: 14111411 -> 14114111-> 14111411-> 11411411

- kkr.ashish January 26, 2014 | Flag
Comment hidden because of low score. Click to expand.
2
of 2 votes

Anonymous, the output of the linear algorithm for the two cases you suggested:
Input:14114111, m=2
Output: 11411411

Input: 14111411, m=2
Output: 11411411

In both cases the output is right.

The linear algorithm uses the same idea as kkr.ashish suggested only instead of iterating through the array and swapping elements, it just stores consecutive identical elements in the form of (element,count) in a stack according to the order of their appearance.
Then it pops elements from the stack and builds a new stack whose elements are yet again of the form (element,count) but the count is not greater than m for all the elements except maybe the element at the top (that's the equivalent of iterating right to left in kkr.ashish's algorithm).
After that we do the same once again with the new stack (the equivalent of iterating left to right in kkr.ashish's algorithm). If the element at the top of the resulting stack has a count greater than m then it's not possible to swap elements correctly. Otherwise, all that's left is to use the order and the count of the elements in the stack to construct the output array.

Run example (stack head is the rightmost element):
Input: {1,4,1,1,1,4,1,1} and m=2

1. Stack1 = {(1,1),(4,1),(1,3),(4,1),(1,2)}
2. Split elements in Stack1:
2.1. pop (1,2) from Stack1
2.2. The count in (1,2) is 2<=m so we push it to Stack2 (Stack2={(1,2)}
2.3. pop (4,1) from Stack1
2.4 The count in (4,1) is 1<=m so we push it to Stack2 (Stack2={(1,2),(4,1)})
2.5. pop (1,3) from Stack2
2.6. The count in (1,3) is 3>m so we need to split it, we push (1,2) to Stack2 (Stack2={(1,2),(4,1),(1,2)}. We update the count in (1,3) to (1,1) because we removed two elements from it. Then we need to find an element other than 1 to insert to Stack2 and with the way we built Stack1 that element is in its head - (4,1). Hence we push (4,1) to Stack2 (Stack2={(1,2),(4,1),(1,2),(4,1)}), we decrement the count of Stack1's head element (Stack1 = {(1,1),(4,0)}). Because the count in the head of Stack1 is 0 we pop this element. Because the head of Stack1 includes the same element (1) as the element we are currently iterating over ((1,1)) we pop it and increase (1,1)'s count by 1 (because the head element we popped is (1,1)).
2.7. Our current element is (1,2=1+1) and Stack1 is empty so we push it to Stack2.
3. Stack2 = {(1,2),(4,1),(1,2),(4,1),(1,2)}. You can see that the count of all elements in Stack2 is already lesser/equal than m=2 which means that the next step is not really necessary but in general the last element in step 2.7 was pushed to Stack2 without checking whether its count is less/equal than m so it might be greater than m.
4. Perform step 2 on Stack2 and store the result in Stack3 (Stack3={(1,2),(4,1),(1,2),(4,1),(1,2)}).
5. The head of Stack3 includes an element whose count is not greater than m which means that a solution is feasible.
6. Fill the output array from Stack3 the same way you created Stack1 in step 1. For Stack3={(1,2),(4,1),(1,2),(4,1),(1,2)}, the output array is {1,1,4,1,1,4,1,1} as desired.

Hopefully its clearer now.

- IvgenyNovo January 26, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Thanks, now I understand how it works. I still can't find a way to prove its correctness, but it seems to work :)

- Anonymous January 26, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Can you please explain output. Do we need to remove excess integers from output or we have to reposition them ??
As what 4 is doing in the end of output?

- SK January 22, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Sorry, just swap the numbers to make smaller groups.

- Fred_Castro January 22, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

output should be like:
1,2,1,1,3,1,4,4,5,4

- SK January 22, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Yeah, changed it, thank you.

But also remember to cover this case:

1,1,1,2,4,4,3,4,4,4 M = 2

- Fred_Castro January 22, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

is output 112344514 correct for input 2,1,1,1,3,4,4,4,5 M = 2 ?
i am using hashtable of size 10 to store occurrence of digits in the number entered.
if any digit is occurring more than M times continuously, I am printing M digits at that time and printing remaining digits later at the end... How's that?

- Anonymous January 22, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

I asked if I could use another structure to store some data and the answer was "I don't think you need it".

- Fred_Castro January 22, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Can you please explain the question? Did you mean any group with size less than M should not contain same integers? Also, I think the group in this case would be formed from continuous sequence of integers?

- Zero2 January 22, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

for instance:

1,1,2 with M = 1 -> 1,2,1 -> 1,1 was a group of same integers with size bigger than M
2,1,1 with M = 1 -> 1,2,1
1,1,1,2,3,3,3,4 with M = 2 -> 1,1,2,1,3,3,4,3

- Fred_Castro January 22, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Input:4,1,1,1,4,1,1,1 m=2.
what is output?

- nate January 30, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

It's 11411411

- Anonymous January 30, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

the code works only for array of size 10 as i have statically defined an array of size 10

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

int main()
{
	int i,p,n=0,m=0,temp;
	int a[10];
	
        printf("enter 10 elements in array");
	for(i=0;i<10;i++)
	scanf("%d",&a[i]);
	
	printf("enter m\n");
	scanf("%d",&m);
	
	n=a[0];
	int c=1;
	
	for(i=1;i<10;i++)
	{
		if(a[i]==a[i-1])
		{
			c++;
		}	
		else
		{
			n=a[i];
			c=1;
		}
		if(c==m+1)
		{
			
			if(i==9)
			p=0;
			else
			p=i+1;
			while(a[p]==a[i])
			{	
				if(p==9)
				p=0;
				else
				p++;
			}
			temp=a[p];
			a[p]=a[i];
			a[i]=temp;
			n=a[i];
			c=1;
		}
	}
	
	for(i=0;i<10;i++)
	printf("%d ",a[i]);
	
	getch();
	
	return 0;
}

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

hashset+moving window?

- lotterier January 22, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 2 vote

Java Code. Complexity O(n). Done by using two array indexes.

public class TestOnly{
	public static void main(String args[]){
		int arr[] = {2,1,1,1,3,4,4,4,5};
		int m = 2;
		
		rearrange(arr,m);
		System.out.println(Arrays.toString(arr));
	}
	
	public static void rearrange(int[] arr,int m){
		int i=0;
		int j=0,count=0;
		while(i<arr.length-1){
			count=1;
			j = i + 1;
			while( j<arr.length && arr[i] == arr[j]){
				count++;
				j++;
			}
			if(count > 2){
				if(j>arr.length -1){
					j = (j % arr.length);
				}
				int tmp = arr[i+m];
				arr[i+m] = arr[j];
				arr[j] = tmp;
				i = i+m;
			}
			i++;
		}
	}
}

- Coder January 22, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
1
of 1 vote

Your code is O(n^2)...
Besides that, what about 4,1,1,1,4,1,1,1?

- Javier January 22, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

#include<stdio.h>
#include<conio.h>
void main()
{
int a[10],i,j,k,value,temp,count,M;
clrscr();
printf("\n\nEnter array:");
for(i=0;i<10;i++)
scanf("%d",&a[i]);
printf("\nEnter M") ;
scanf("%d",&M);

printf("\nYour array :");
for(i=0;i<10;i++)
printf(" %d",a[i]);

count=0;
for(i=0;i<10;i++)
{
count=0;
for(j=i;j<10;j++)
{
if(a[i]==a[j])
count++;
else
break;
if(count>M)
{
for(k=j;k<10;k++)
{
if(a[j]!=a[k])
{
value=a[k];
break;
}
}
temp=a[j];
a[j]=value;
a[k]=temp;
break;
}
}
}
printf("\nYour Output:");
for(i=0;i<10;i++)
printf(" %d",a[i]);
getch();
}

- Rajat January 23, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

#include<stdio.h>
#include<conio.h>
void main()
{
int a[10],i,j,k,value,temp,count,M;
clrscr();
printf("\n\nEnter array:");
for(i=0;i<10;i++)
scanf("%d",&a[i]);
printf("\nEnter M") ;
scanf("%d",&M);

printf("\nYour array :");
for(i=0;i<10;i++)
printf(" %d",a[i]);

count=0;
for(i=0;i<10;i++)
{
count=0;
for(j=i;j<10;j++)
{
if(a[i]==a[j])
count++;
else
break;
if(count>M)
{
for(k=j;k<10;k++)
{
if(a[j]!=a[k])
{
value=a[k];
break;
}
}
temp=a[j];
a[j]=value;
a[k]=temp;
break;
}
}
}
printf("\nYour Output:");
for(i=0;i<10;i++)
printf(" %d",a[i]);
getch();
}

- Rajat January 23, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

/*
c#
*/
        static int[] GroupOfIntegers(int[] unOrdered, int m)
        {
	        if(unOrdered == null)
		        throw new ArgumentNullException();

	        SortedDictionary<int, int> grouped = new SortedDictionary<int,int>();

	        foreach(int i in unOrdered)
	        {
		        if(grouped.Keys.Contains(i))
			        grouped[i]++;
		        else
			        grouped.Add(i, 1);
		
	        }

            int[] ordered = new int[unOrdered.Count()];
            int z = 0;
                
	        foreach(KeyValuePair<int, int> kvp in grouped)
	        {                
		        for(int i = 0; (i <= m - 1) && (i <= kvp.Value -1); i++)
		        {
			        Console.Write("{0} ", kvp.Key);
			        ordered[z] = kvp.Key;		
		        }
                z++;
	        }

            Console.ReadLine();
	        return ordered;
        }

- E January 23, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

public static int[] process(int[] arr, int m) {
		int current = 0, j = 0;
		int count = 1;
		int last = -1;

		int i = arr.length - 1;
		while (i > 0) {
			if (arr[i] == last) {
				count++;

				if (count > m) {
					current = i;
					j = current - 1;
					// find the next different element
					while (j > 0 && arr[j] == last) {
						j--;
					}

					// swap arr[j] <-> arr[current]
					int temp = arr[j];
					arr[j] = arr[current];
					arr[current] = temp;

					count = 1;
				}
			} else {
				count = 1;
			}
			last = arr[i];
			i--;
		}
		return arr;
	}

- addsjunior January 26, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Wrong for: { 1, 1, 1, 1, 2 }

- andre.azevedo January 31, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

import java.util.Arrays;


public class Unordered_Array {


public static int[] swap (int a [] , int k, int j)
{
int temp;
temp = a[k];
a[k] = a[j];
a[j] = temp;

return a;
}

public static void main(String[] args)
{
int [] a = new int []{2,1,1,1,3,4,4,4,5};
int i=0,j=-1,k=0,count=1,first;
int M=2;

while (j < a.length-1)
{

first = a[i];
j = j+1;

if(first == a[j])
{


count ++;

if (count > M)
{
k = j+1;

while (first == a[k])
{
k++;
if (k == a.length)
{
break;
}
}

if (k == a.length)
{
System.out.println("Not Applicable");
break;
}
else
{
a = swap(a,k,j);
i = j+1;
j=i;
count =1;
}

}


}
else
i=j;

}

System.out.println(Arrays.toString(a));

}

}

- AJAY ANTHONY January 27, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

import java.util.Arrays;


public class Unordered_Array {


public static int[] swap (int a [] , int k, int j)
{
int temp;
temp = a[k];
a[k] = a[j];
a[j] = temp;

return a;
}

public static void main(String[] args)
{
int [] a = new int []{2,1,1,1,3,4,4,4,5};
int i=0,j=-1,k=0,count=1,first;
int M=2;

while (j < a.length-1)
{

first = a[i];
j = j+1;

if(first == a[j])
{


count ++;

if (count > M)
{
k = j+1;

while (first == a[k])
{
k++;
if (k == a.length)
{
break;
}
}

if (k == a.length)
{
System.out.println("Not Applicable");
break;
}
else
{
a = swap(a,k,j);
i = j+1;
j=i;
count =1;
}

}


}
else
i=j;

}

System.out.println(Arrays.toString(a));

}

}

- AJAY ANTHONY January 27, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

def rearange(list: List[Int], m: Int): List[Int] = {
    import Math._

    def fill(n: Int, i: Int) =
      List.tabulate(n)(_ => i)

    def findFreq(l: List[(Int, Int)]) =
      if(l.length < 2) (l.head, Nil)
      else l.tail.foldLeft((l.head, List.empty[(Int, Int)])) {
        case ((a @ (_, c1), lst), b @ (_, c2)) => if(c1 > c2) (a, b :: lst) else (b, a :: lst)
      }

    def H(e: (Int, Int), l: List[(Int, Int)]) = 
      min(m, (l.map { case (_, c) => c }.sum + 1) / ((e._2 + m - 1) / m))

    def rearange0(f: (Int, Int), lst: List[(Int, Int)], dx: Int): List[Int] = {
      if(dx == 0) ???

      (f, lst) match {
        case ((_, c), l @ (_ :: _)) if c == 0 => 
          val (e, t) = findFreq(l)
          rearange0(e, t, H(e, t))

        case ((k1, c1), l @ (_ :: _)) =>
          val ((k2, c2), t) = findFreq(l)
          val (s1, s2) = (min(c1, m), min(c2, dx))
          val tail = (if(c2 - s2 > 0) (k2, c2 - s2) :: t else t)
          fill(s1, k1) ::: fill(s2, k2) ::: rearange0((k1, c1 - s1), tail, dx)

        case ((k, c), Nil) =>
          fill(c, k)
      }
    }

    val base = list
      .groupBy { x => x }
      .mapValues { _.length }
      .toList

    if(list.length == 0) Nil
    else if(base.length == 1) {
      if(list.length > m) Nil
      else list
    }
    else {
      val (e, t) = findFreq(base)
      rearange0(e, t, H(e, t))
    }
  }

- Yuriy January 29, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

variation of kadane algorithm...

- Anonymous January 31, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

//keep the running count of only the current repeating integer 

void modify(int arr[],int n,int M)
{
    int i,count = 0;
    //count holds count of repeating integer
    for(i = 0; i < n-1; i++)
    {
        if(count == 0 || count <= M)       //no character in continuation or allowed sequence
        {
        if(count == 0)
        count = 1;            //at least one occurence
        while(i != n-1 && arr[i] == arr[i+1])
        {
            count++;
            i++;
        }
        //now arr[i] != arr[i+1] or i = n-1
        if(count > M)
        {
            if(i == n-1)     //all characters repeating can't do a thing
            break;
            //else arr[i] != arr[i+1]
            swap(arr+i+1,arr+i-count+M+1);
            count -= M;
        }
        else              //repetition is less than M,stay at original location
        count = 0;       //since count < M and arr[i] != arr[i+1] 
       }
       else
       {
           //count > M
           if(i != n-1 && arr[i] == arr[i+1])
           {
               count++;
               i++;
           }
           //count > M definitely
           if(i == n-1)
           break;
           swap(arr+i+1,arr+i-count+M+1);
           count -= M;
       }
    }
}

- Sumit Monga February 07, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

sorry there are some mistakes in the code like in comments i have written characters and major mistake is in the else part i wrote if instead of while . I am giving the correct and checked code with time complexity O(n) ,check it out:---

void modify(int arr[],int n,int M)
{
    int i,count = 0;
    //count holds count of repeating integer
    for(i = 0; i < n; i++)
    {
        if(count <= M)      
        {
        if(count == 0)
        count = 1;            //new integer
        while(i != n-1 && arr[i] == arr[i+1])
        {
            count++;
            i++;
        }
        //now arr[i] != arr[i+1] or i = n-1
        if(count > M)
        {
            if(i == n-1)     //reached the end 
            break;
            //else arr[i] != arr[i+1]
            swap(arr+i+1,arr+i-count+M+1);     //take M integers of this sequence 
            count -= M;                         //reduce count by M
        }
        else
        count = 0;             //count <= M and arr[i] != arr[i+1] so set count for next integer
        }
       else
       {
           //count > M
           while(i != n-1 && arr[i] == arr[i+1])
           {
               count++;
               i++;
           }
        
           if(i == n-1)
           break;
           swap(arr+i+1,arr+i-count+M+1);     //take M integers of this sequence 
           count -= M;                         //reduce count by M
       }
    }
}

- Sumit Monga February 07, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

I found an O(n log(n)) solution.

I first find the number of occurrences of each object.

Then, break each number into batches of "M" repetitions, i.e., one Run.
Example:
sequence: 1, 1, 1, 1, 4, 4, 1
M = 2
Runs: (1, 1), (1, 1), (1) for type = 1
(4, 4) for type = 4


An object "Type" is defined as a set of Runs of same type. Type1 > Type2 if Type1 has more runs. This way, I can sort all Types descending. This is of course O(nlog(n)).

Lets assume "1" is the type with largest number of runs. Now if the total number of "other" runs is equal or greater than the number of runs of "1", we can proceed to making a proper output ("MakeSequence()" routine). Otherwise, I will break the runs into smaller runs until that happens. If not, then there is no solution. This step is linear in the number of Runs() < number of elements.

To make the sequence we do this:
a) Take out head of line in queue and remove one run add to sequence. If the Type is empty now, throw it away. If not, keep it somewhere but don't put in queue.

b) Take out another type. Add to sequence. If non-empty, keep it somewhere.

c) Now if there is a type outside, put it back into queue.

e) go back to a) until queue is empty.

Example (above):
Type1 = [(11), (11), (1)]
Type2= [(4,4)]
since Type1.nRuns() == 3 > Type2.nRuns() + 1, we will break Type2.
Type2=[(4),(4)].
Now we go to make sequence:
seq = "";
a)-> seq = "11", Type1 = [(1,1),(1)];
b)->seq="4",Type2=[(4)],
c) Type1 goes back into queue.
a)-> seq="11411"
b)->seq="114114";
c)->Type1 goes back in
a)->seq="1141141"
done!

here is the code:

public class SequenceSeparation {
    public static int M = 2;
    public static class Run  {
        String value;
        int length;
        
        public int getLength() {
            return length;
        }
        public Run(String value) {
            this.value = value;
            this.length = 1;
        }
        
        public void add() {
            length++;
        }
        public LinkedList<Run> breakRun(int n) {
            LinkedList<Run> runs = new LinkedList<>();            
            while (n != 0 && length != 1) {
                Run r = new Run(value);
                runs.add(r);
                n--;
                length--;
            }           
            runs.add(this);
            return runs;
        }
        @Override
        public String toString() {
            String s = "";
            for (int i = 0; i < length; i++)
                s = s + value;
            return s;
        }
    }
    
    public static class Type implements Comparable<Type> {
        String value;
        int buffer = 0;
        Run current_run = null;
        LinkedList<Run> runs;
        public Type(String value) {
            this.value = value;
            runs = new LinkedList<>();
            current_run = new Run(value);
            runs.add(current_run);
            buffer = 1;
        }
        
        public Run nextRun() {
            if (runs.isEmpty())
                return null;
            else
                return runs.pollFirst();
        }
        public void add() {
            if (buffer == 0) {
                current_run = new Run(value);
                runs.add(current_run);
                buffer = 1;
            }
            else {
                current_run.add();
            }
            if (current_run.length == M)
                buffer = 0;
        }
        
        public String getValue() {
            return value;
        }
        public Integer nRuns() {
            return runs.size();
        }
        
        @Override
        public int compareTo(Type o) {
            return -nRuns().compareTo(o.nRuns());
        }
                
        public int increaseRuns(int n) {                        
            Run first_run = null;
            while (true) {        
            Run r = runs.getFirst();
            if (first_run == null)
                first_run = r;
            else
                if (first_run == r)
                    return n;
            int c = runs.size();
            while (r.getLength() == 1) {
                runs.removeFirst();
                runs.addLast(r);
                r = runs.getFirst();
                c--;
                if (c == 0)
                    return n;
            }
           
            LinkedList<Run> new_runs = r.breakRun(n + 1);
           
            runs.removeFirst();
            int ii = new_runs.size();
            for (int i = 0; i < ii; i++) {
                Run rr = new_runs.pollFirst();
                runs.addLast(rr);
            }         
            n -= (ii - 1);
            if (n == 0)
                return 0;
        }
    }
    }

    public SequenceSeparation(String sequence, int M) {
        SequenceSeparation.M = M;
        String[] types = sequence.split(",");
        HashMap<String, Type> repetitions = new  HashMap<>();
        // Round 1: count        
        Type max_type = null;
        int ng = 0;
        for (String t : types) {
            if (repetitions.containsKey(t))
                repetitions.get(t).add();
            else
                repetitions.put(t, new Type(t));            
            if (repetitions.get(t).nRuns() > ng) {
                ng = repetitions.get(t).nRuns();
                max_type = repetitions.get(t);
            }                
        }
               
        int n_total_other = 0;                
        for (String t : repetitions.keySet()) {
            if (t.compareTo(max_type.getValue()) != 0)
                n_total_other += repetitions.get(t).nRuns();                
        }
        if (n_total_other + 1 < max_type.nRuns()) {
            int diff = max_type.nRuns() - n_total_other - 1;
            for (String t : repetitions.keySet()) {
                if (t.compareTo(max_type.getValue()) != 0) {
                Type type = repetitions.get(t);
                diff = type.increaseRuns(diff);
                }               
            }  
            if (diff > 0) {
                System.out.println("Could not resolve.");
                return;
            }                          
        }
        MakeSequence(repetitions);        
    }
    private void MakeSequence(HashMap<String, Type>  repetitions) {
        // A sorted-queue : MaxHeap (note the comparedTo defition for Type)
        PriorityQueue<Type> queue = new PriorityQueue<>(repetitions.values());
        Type type1 = null, type2 = null;
        String seq = "";
        while (queue.isEmpty() == false) {
            type2 = type1;
            Type next = queue.poll();
            seq += next.nextRun().toString();
            if (next.nRuns() > 0)
                type1 = next;    
            else
                type1 = null;
            if (type2 != null)
                queue.add(type2);
        }
        System.out.println("Solution:");
        System.out.print(seq);
    }
}

- Ehsan February 07, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 2 vote

O(nlog(n)) solution

import java.util.Arrays;
import java.util.Scanner;


public class No_size_bigger {
	
	static void Print_no_Bigger(int [] array,int M){
		
		Arrays.sort(array);
		
		int Number_of_occurences=1;
		int current_Number=array[0];
		System.out.print(current_Number+" ");
		
		for(int i=1;i<array.length;i++){
			
			if(array[i]==current_Number){
				Number_of_occurences++;
				if(Number_of_occurences<=M){
					System.out.print(array[i]+" ");
					
				}
				
			}else{
				current_Number=array[i];
				 Number_of_occurences=1;
				 System.out.print(array[i]+" ");
				
			}
			
		}
		
		
		
		
	}
	
	
	public static void main(String [] args){
		
		Scanner input=new Scanner(System.in);
		
		
		
		int [] array={2,1,1,1,3,4,4,4,5,5,5,5,7,7,8,8,8,9,9,9,9};
		
		
		 Print_no_Bigger(array,3);
	
		
	}

}

- yolo February 07, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Hello, thank you for sharing your solution. Your solution is similar to the solution to "Remove Duplicates in Sorted Array II" in Leetcode. However, I think this problem is different because it requires you to relocate the numbers so that no consecutive same numbers of size larger than M is allowed, rather than just ignoring numbers as you did in your solution.

- Anonymous August 31, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Python:

def nobigger(l, m, last=None, count=0):
    if len(l) >= m:
        if l[0] == last and count < m-1:
            return [l[0]] + nobigger(l[1:], m, last, count+1)
        elif l[0] == last:
            return nobigger(l[1:], m, last, count+1)
        else:
            return [l[0]] + nobigger(l[1:], m, l[0], 0)
    else:
        return l
    
print nobigger([2,1,1,1,3,4,4,4,5], 2)

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

Scan the numbers and store it in a Hashmap.
Hashmap : (number,count)

if the size of the group is m.
Iterate through the HashMap, picking up m different elements and reducing the count.

perform the above operation n/m times

Thus the overall complexity = O(n) {for updating hashMap}+O(n){for iterating through HashMap}
=O(n)

- Dinesh March 24, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

public class Solution{
public void trans(int [] A ,int M){
for(int i = 0 ; i < A.length - 1; ){
int j = i + 1, count = 1;
while(j < A.length){
if(A[j] == A[j - 1]) {
count ++;
j ++;
}
else {
if(count <= M) { i = j; break;}
int tmp = A[i + M ];
A[i + M ] = A[j];
A[j] = tmp;
count -= M - 1;
j++;
i = i + M + 1;
}
}
if(j == A.length ) break;
}




}
public void solve(int [] A , int M){
trans(A, M);
reverse(A);
trans(A , M);
}
public void reverse(int [] A){
for(int i = 0 ; i < A.length /2 ; i++) {
int tmp = A[i];
A[i] = A[A.length - 1 - i];
A[A.length - 1 -i] = tmp;
}
}

}

- Haoqing April 18, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

public class Solution{
	public void trans(int [] A ,int M){
            for(int i = 0 ; i < A.length - 1; ){
                int j = i + 1, count = 1;
		while(j < A.length){
			if(A[j] == A[j - 1]) {
				count ++;
				j ++;
			} 
			else {
				if(count <= M) { i = j; break;} 
				int tmp = A[i + M ];
				A[i + M ] = A[j];
				A[j] = tmp;
				count -= M - 1;
				j++;
				i = i + M + 1;	
			}
		}
                if(j == A.length ) break;
	}


		 

    }
	public void solve(int [] A , int M){
		trans(A, M);
		reverse(A);
		trans(A , M);
	}
	public void reverse(int [] A){
		for(int i = 0 ; i < A.length /2 ; i++) {
			int tmp = A[i];
			A[i] = A[A.length - 1 - i]; 	
			A[A.length - 1 -i] = tmp;
		}
	}

}

- Hq April 18, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

O(n) Solution.
Go through the list twice.
The first pass is to try to find right hand side number to slice the left consecutive sequence. The second pass is the other way around.
Solution assumes an answer exists.
Proof:
Assume an answer exists.
The first pass could only possibly leave the right most consecutive to be invalid. The second pass would leave the first to be invalid. Since in the first pass we already make sure the first(left most) consecutive sequence to be valid , the only reason for the left most to be invalid is it has the same value as the right most sequence. Consider the example (1,1,2,2,3,3,1,1,1,1,1,1........) the 1 would propagate to the left. If the left most sequence becomes invalid, we can infer no answer exists, where contradiction occurs.

public class Solution{
	public void trans(int [] A ,int M){
            for(int i = 0 ; i < A.length - 1; ){
                int j = i + 1, count = 1;
		while(j < A.length){
			if(A[j] == A[j - 1]) count++;
			else {
				if(count <= M) { i = j; break;} 
				int tmp = A[i + M ];
				A[i + M ] = A[j];
				A[j] = tmp;
				count -= M ;
				i = i + M + 1;	
			}
                        j++;
		}
                if(j == A.length ) break;
	}
    }
	public void solve(int [] A , int M){
		trans(A, M);
		reverse(A);
		trans(A , M);
	}
	public void reverse(int [] A){
		for(int i = 0 ; i < A.length /2 ; i++) {
			int tmp = A[i];
			A[i] = A[A.length - 1 - i]; 	
			A[A.length - 1 -i] = tmp;
		}
	}

}

- Hq April 19, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

func(arr, m);
	int i = 0;
	int j = arr.length -1;
	while(i < j)
	{
		int temp = arr[i];
		arr[i] = arr[j];
		arr[j] = temp;
		++i;
		--j;
	}
	func(arr, m);

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

func(int[] arr, int m)
{
if(m < 1 || arr == null) throw new IllegalArgumentException();
int index = 0;
int upto = arr.length - m;
while(index < upto)
{
	int firstVal = arr[index];
	int count = 1;
	for(int i=index+1; i<=(index + m); ++i)
	{
			if(firstVal == arr[i])
			{
				count++;
			}else
			{
				break;
			}
	}
	if(count > m)
	{
		int newIndex = index + m + 1;
		while(newIndex < arr.length)
		{
			if(firstVal != arr[newIndex])
			{
					int temp = arr[index + m];
					arr[index + m] = arr[newIndex];
					arr[newIndex] = temp;
					index = index + m;
					break;
			}
			++newIndex;
		}	
	}
	++index;
}

}

- pratik May 21, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 2 vote

Below is an inplace code:

#include<iostream>
#include<conio.h>
using namespace std;

void remDup(int a[],int n,int m){
     int i=0,j=0,k=0;
     while(i<n){
                k=0;
                if(i+1<n&&a[i]!=a[i+1]) a[j++]=a[i++];             //if it is not duplicated at all
                while(i<n-1&&a[i]==a[i+1]&&k<m){                        //copy all duplicates till k<m
                                         a[j++]=a[i++];
                                         k++;
                                         }
                if(k<m) a[j++]=a[i];     //copy the last element if k<m
                while(i+1<n&&a[i]==a[i+1]) i++; //skip all the othr same elements
                i++;
                }
     if(k<m&&a[i-1]!=a[i-2]) a[j++]=a[i-1];     //last element is copied if it can be taken
     for(int i=0;i<j;i++) cout<<a[i]<<" ";
     }

int main(){
    int a[]={2,1,1,1,3,4,4,4,4,5,5,5,6,6,7,8};
    int n=16,m=2;
    remDup(a,n,m);
    getch();
    }

- alex September 29, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Seems to work!

- ssss September 29, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

public static int[] arrayFormat(int[] a, int m) {
int count = 0;
int i = 0;
int len = a.length;
while (i<len-1) {
if(a[i] == a[i+1]) {
count++;
if(count >= m) {
a = adjustPos(a, i);
}
} else {
count = 0;
}
len = a.length;
i++;
}

return a;
}
public static int[] adjustPos(int [] a, int pos) {
int [] ad = new int[a.length -1];
for (int i = 0; i < pos; i++) {
ad[i] = a[i];
}
for (int i = pos; i < a.length-1; i++) {
ad[i] = a[i+1];
}
return ad;
}

- Anonymous October 01, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

This is Java solution with running complexity of O(2n) = O(n)
and space complexity of O(2n) = O(n)

I might lower to space complexity to only one extra array but the solution will be less clean.

public static int[] removeKDuplicates(int[] list, int k)
	{
		// i use ArrayList because the final size is unknown
		ArrayList<Integer> newList = new ArrayList<Integer>();
		int counter = 0;

		// since the integers are positive -1 must be unique
		int prev = -1;

		for (int current : list)
		{	if ( prev == current )
			{	
				++counter;
				if ( counter >= k) 
				{
					continue;	
				} 
			}else
			{
				counter = 0;
				prev = current;
			}
				
			newList.add(current);
		}
		
		// copy the Array to int[]
		int[] returnedList = new int[newList.size()];
		for (int i = 0; i < returnedList.length ; i++)
		{
			returnedList[i] = newList.get(i);
		}
		
		return returnedList;
	}

- O(ren) :) January 22, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

My Algorithm:
1) Keep pointer to start and end of array.
2) keep on counting number from start if ( cur_num == prev_num) count++; and do start++.
3) if (count > k), then swap(cur_elem, last_elem) and decrement last pointer (last--); but don't do start++ at this step.
4) Now check the (2) condition for swapped element and (cur_elem != prev_elem) then, do start++, and last = n-1;
5) keep on doing same thing until (start == last)

- ~amit April 10, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

In Java:

private void arrangeTwoEqualsMax() {
    	
    	int[] array = new int[]{2,1,1,1,3,4,4,4,5};
    	
    	for (int i = 0; i < array.length - 3; i++) {
    		if (array[i] == array[i+1] && array[i] == array[i+2]) {
    			findDifferent(array, i + 2);
    			
    		}
    	}
    	
    	System.out.println("Arranged array: " + Arrays.toString(array));
    	
    }
    
    
    private void findDifferent(int[] array, int index) {
    	
    	if (array[index] == array[index + 1]) {
    		findDifferent(array, index + 1);
    		
    	} else {
    		int temp = array[index + 1];
    		array[index + 1] = array[index];
    		array[index] = temp;
    	}
    }

- manuel April 14, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.PriorityQueue;

public class GroupElementInSizeM{
    class Node{
        int key;
        int freq;
        public Node(int key, int freq) {
            this.key = key;
            this.freq = freq;
        }
    }
    public int[] groupinSizeM(int[] intArray, int M) {
        if (intArray == null || intArray.length == 0) {
            return intArray;
        }
        Comparator<Node> nodeComp = new Comparator<Node>() {
            public int compare(Node n1, Node n2) {
                return n2.freq - n1.freq;
            }
        };
        PriorityQueue<Node> maxHeap = new PriorityQueue<>(nodeComp);
        Map<Integer, Integer> freqMap = new HashMap<>();
        for (int i : intArray) {
            if (freqMap.containsKey(i)) {
                freqMap.put(i, freqMap.get(i) + 1);
            } else {
                freqMap.put(i, 1);
            }
        }
        for (int key : freqMap.keySet()) {
            maxHeap.add(new Node(key, freqMap.get(key)));
        }
        int pointer = 0;

        while (!maxHeap.isEmpty()) {

            Node v = maxHeap.poll();
            int maxPossible = (pointer != 0 && v.key == intArray[pointer - 1]) ? M - 1 : M;
            for (int i = 0; i < Math.min(maxPossible, v.freq); i++) {
                intArray[pointer++] = v.key;
            }
            v.freq -= Math.min(maxPossible, v.freq);
            if (v.freq > 0) {
                if (maxHeap.isEmpty()) {
                    return null;
                }
                Node next = maxHeap.poll();
                intArray[pointer++] = next.key;
                next.freq--;
                if (next.freq > 0) {
                    maxHeap.add(next);
                }
                maxHeap.add(v);
            }

        }
        return intArray;
    }

}

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

import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.PriorityQueue;

public class GroupElementInSizeM{
    class Node{
        int key;
        int freq;
        public Node(int key, int freq) {
            this.key = key;
            this.freq = freq;
        }
    }
    public int[] groupinSizeM(int[] intArray, int M) {
        if (intArray == null || intArray.length == 0) {
            return intArray;
        }
        Comparator<Node> nodeComp = new Comparator<Node>() {
            public int compare(Node n1, Node n2) {
                return n2.freq - n1.freq;
            }
        };
        PriorityQueue<Node> maxHeap = new PriorityQueue<>(nodeComp);
        Map<Integer, Integer> freqMap = new HashMap<>();
        for (int i : intArray) {
            if (freqMap.containsKey(i)) {
                freqMap.put(i, freqMap.get(i) + 1);
            } else {
                freqMap.put(i, 1);
            }
        }
        for (int key : freqMap.keySet()) {
            maxHeap.add(new Node(key, freqMap.get(key)));
        }
        int pointer = 0;

        while (!maxHeap.isEmpty()) {

            Node v = maxHeap.poll();
            int maxPossible = (pointer != 0 && v.key == intArray[pointer - 1]) ? M - 1 : M;
            for (int i = 0; i < Math.min(maxPossible, v.freq); i++) {
                intArray[pointer++] = v.key;
            }
            v.freq -= Math.min(maxPossible, v.freq);
            if (v.freq > 0) {
                if (maxHeap.isEmpty()) {
                    return null;
                }
                Node next = maxHeap.poll();
                intArray[pointer++] = next.key;
                next.freq--;
                if (next.freq > 0) {
                    maxHeap.add(next);
                }
                maxHeap.add(v);
            }

        }
        return intArray;
    }

}

- dogabi June 18, 2016 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

my implementation based on more rated post

public void ArrengeByWindow(int[] a, int m)
{
    var set = new HashSet<int>();
            
    for (int i=0; i < a.Length; i++)
    {
        if (set.Contains(a[i]))
        {
            int j = a.Length - 1;
            while (j > i)
            {
                if (set.Contains(a[j]))
                    j--;
                else
                {
                    int tmp = a[i];
                    a[i] = a[j];
                    a[j] = tmp;
                    break;
                }
            }

            if (i == j)
                throw new Exception();
        }

        set.Add(a[i]);
        if (set.Count == m)
            set.Clear();
    }
}

- hnatsu November 21, 2016 | 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