Google Interview Question for Software Engineer / Developers


Country: United States
Interview Type: Phone Interview




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

public class Pattern {

public static void main(String[] args){

int[] input={1,2,3,4,7,6,5,2,3,4,1,2}; //N
int startIndex=0;
int runs=10; //M
int no = 10; //K
int diff = 10; //L


while(startIndex+1<input.length){

if(input[startIndex]<no || input[startIndex+1]<no || Math.abs(input[startIndex]-input[startIndex+1])>diff )
continue;

Mode mode=getMode(input[startIndex],input[startIndex+1]);
System.out.print("{"+input[startIndex]+",");
++startIndex;
while(startIndex+1<input.length){

if(input[startIndex]>no || input[startIndex+1]>no || Math.abs(input[startIndex]-input[startIndex+1])>diff )
break;

if(mode==getMode(input[startIndex],input[startIndex+1])){

System.out.print(input[startIndex]+",");
++startIndex;
}
else
{
break;
}
}

System.out.println(input[startIndex]+"}");
--runs;

if(runs<=0)
return;

}

//System.out.println("Hi");
}

private static Mode getMode(int num1,int num2){

if(num1>num2)
return Mode.Decreasing;
else
return Mode.Increasing;


// return null;
}

}

enum Mode{Increasing,Decreasing}

- Nish March 15, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

I suppose this solution is correct: ie. do simple bruteforce
approach (recursive), and count the number of runs
in each step. We do not need to explore the paths where the # of runs is greater than M.

here is the code, please correct me if I am wrong:

int total_count = 0;
int N = 5, M = 2, K = 6, L = 1;
std::vector< int > seq;

// n_placed: number of digits in a sequence being placed
// n_last: last digit placed (for comparison)
// n_runs: # of runs counted so far
// dir: current direction: decreasing(0), increasing(1) or undefined(-1)
void count_sequences(int n_placed, int n_last, int n_runs, int dir) {
    seq.push_back(n_last);
    if(n_placed == N) {
        if(n_runs == M) {
            total_count++;
            printf("%d: ", total_count);
            for(typeof(seq.begin()) i = seq.begin(); i != seq.end(); i++) {
                printf("%d ", *i);
            }
            printf("\n");
        }
        seq.pop_back();
        return;
    }
    
    for(int i = 1; i <= K; i++) {
        int diff = i - n_last;
        // difference between adjacent elements is too large
        if(ABS(diff) > L)
            continue;
        
        if(diff == 0) { // duplicate element: break the current sequence
            // have enough runs: no need to explore this path
            if(n_runs == M) 
                continue;
            count_sequences(n_placed+1, i, n_runs+1, -1);
        } else if(diff < 0) {
            if(dir == -1) { // start a new decreasing sequence
                count_sequences(n_placed+1, i, n_runs, 0);
            // current sequence is decreasing: continue this sequence
            } else if(dir == 0) {
                count_sequences(n_placed+1, i, n_runs, 0);
            // current sequence is increasing: break it
            } else { // dir == 1
                if(n_runs == M) // have enough runs already
                    continue;
                count_sequences(n_placed+1, i, n_runs+1, 0);
            }
        } else { // diff > 0

            if(dir == -1) { // start a new increasing sequence
                count_sequences(n_placed+1, i, n_runs, 1);
            // current sequence is increasing: continue this sequence
            } else if(dir == 1) {
                count_sequences(n_placed+1, i, n_runs, 1);
            // current sequence is decreasing: break it
            } else { // dir == 0
                if(n_runs == M) // have enough runs already
                    continue;
                count_sequences(n_placed+1, i, n_runs+1, 1);
            }
        }
    }
    seq.pop_back(); // pop the current element
}

int main() {
    for(int i = 1; i <= K; i++) {
        count_sequences(1, i, 1, -1);
    }
    return 1;
}

e.g., for N = 5, M = 2, K = 6, L = 1 we get:

1: 1 1 2 3 4
2: 1 2 2 3 4
3: 1 2 3 2 1
4: 1 2 3 3 2
5: 1 2 3 3 4
6: 1 2 3 4 3
7: 1 2 3 4 4
8: 2 1 1 2 3
9: 2 1 2 3 4
10: 2 2 3 4 5
11: 2 3 3 2 1
12: 2 3 3 4 5
13: 2 3 4 3 2
14: 2 3 4 4 3
15: 2 3 4 4 5
16: 2 3 4 5 4
17: 2 3 4 5 5
18: 3 2 1 1 2
19: 3 2 1 2 3
20: 3 2 2 3 4
21: 3 2 3 4 5
22: 3 3 4 5 6
23: 3 4 3 2 1
24: 3 4 4 3 2
25: 3 4 4 5 6
26: 3 4 5 4 3
27: 3 4 5 5 4
28: 3 4 5 5 6
29: 3 4 5 6 5
30: 3 4 5 6 6
31: 4 3 2 1 1
32: 4 3 2 1 2
33: 4 3 2 2 1
34: 4 3 2 2 3
35: 4 3 2 3 4
36: 4 3 3 2 1
37: 4 3 3 4 5
38: 4 3 4 5 6
39: 4 4 3 2 1
40: 4 5 4 3 2
41: 4 5 5 4 3
42: 4 5 6 5 4
43: 4 5 6 6 5
44: 5 4 3 2 2
45: 5 4 3 2 3
46: 5 4 3 3 2
47: 5 4 3 3 4
48: 5 4 3 4 5
49: 5 4 4 3 2
50: 5 4 4 5 6
51: 5 5 4 3 2
52: 5 6 5 4 3
53: 5 6 6 5 4
54: 6 5 4 3 3
55: 6 5 4 3 4
56: 6 5 4 4 3
57: 6 5 4 4 5
58: 6 5 4 5 6
59: 6 5 5 4 3
60: 6 6 5 4 3

- 111 April 03, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

lets take an array A[1...P] (P > N).

We make an array with the runs arr[1.. P] R where all the elements from single run (except the last one which goes in the next sequence) are colored the same (have same number).

(All the sub arrays bellow are marked just with indexes)
Follow L Rule: So lets split the array to a sub arrays that follow the L rules. We make an help array B[1..P](I used it to build R array) which we fill with the difference between the current and previous elements (B[i] = A[i] - A[i - 1]) and we split the array on the point where abs(B[i]) > L. Now we have sub arrays that follow the L rule.

Follow the K rule: here we just split the sub arrays from above(after L rule) on the points where A[i] > K;

Follow the N and M rule: here we iterate all possible sub arrays with length = N and count the color change in R to be equal to M.
If tall the rules are true we count++;

- GKalchev March 15, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

It seems there is a mistake in the task description. Any valid sequence can be converted to infinite number of valid sequences by subtracting 1,2,3,... from every element (numbers can be negative by definition). So, with this description amount can be either 0 or infinity.

- trebuchet March 20, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;

public class GoogleSequence {


	class Seq {

		private LinkedList<LinkedList<Integer>> sets;

		public Seq(LinkedList<LinkedList<Integer>> sets) {
			this.sets = sets;
		}
		
		@Override
		public String toString() {
			// TODO Auto-generated method stub
			return sets.toString();
		}
	}
	
	public LinkedList<Seq> calculate(int N, int M,
			int K, int L) {
		// pos seq of N
		// with M runs
		// nums in seq <= K
		// adj diff <=L

		LinkedList<LinkedList<Integer>> lists = new LinkedList<LinkedList<Integer>>();

		for (int j = 0; j < N; j++) {
			int size = lists.size();

			if (size == 0) {
				for (int i = 1; i <= K; i++) {
					LinkedList<Integer> newL = new LinkedList<Integer>();
					newL.add(i);
					lists.add(newL);
				}
			}

			LinkedList<Integer> list = null;
			for (int s = 0; s < size; s++) {
				list = lists.get(s);
				LinkedList<Integer> newL = new LinkedList<Integer>(list);
				for (int i = 1; i <= K; i++) {
					LinkedList<Integer> temp = new LinkedList<Integer>();
					if (i == 1) {
						list.offerLast(i);
					} else {
						temp.addAll(newL);
						temp.offerLast(i);
						lists.offerLast(temp);
					}
				}
			}

		}


		LinkedList<Integer> pk = lists.peekLast();
		LinkedList<Seq> finalLists = new LinkedList<Seq>();

		for (LinkedList<Integer> list : lists) {
			int index = 0;
			LinkedList<LinkedList<Integer>> sets = new LinkedList<LinkedList<Integer>>();
			while (list.size() > 0 && (index+1)<list.size()) {
				int prev = list.get(index);
				int next = list.get(index+1);
				
				if (prev + L != next && prev - L != next) {
					List<Integer> sub = list.subList(0, index+1);
					sets.add(new LinkedList<Integer>(sub));
					if (list.size() >= index){
						list = new LinkedList<Integer>(list.subList(index+1,
								list.size()));
					index = 0;
					}
				}else{
					index++;
					if (index+1==list.size()){
						sets.add(list);
					}
				}

			}

			if (sets.size() == M) {

				finalLists.add(new Seq(sets));
			}

		}

		return finalLists;

	}

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		GoogleSequence seq = new GoogleSequence();
		System.out.println("Type four numbers, N M K L");
		LinkedList<Seq> lists = seq.calculate(sc.nextInt(),
				sc.nextInt(), sc.nextInt(), sc.nextInt());
		System.out.println("POSSIBLE:" + lists.size());

		for (Seq linkedList : lists) {
			System.out.println(linkedList.toString());
		}

	}
}

- Pavlos Gi March 22, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

It would be great if you could explain your logic

- Chinmaya March 22, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

I got one of the result as: [[9], [5], [7, 4, 7]]
Is this a valid result? If yes, i think i misunderstood the question. Can you explain why it's a valid seq?

- swapsmagic March 23, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Well from what I understood the question wanted you to find all sequence of numbers that met the four criteria. For example N=5, M=3, K=9,L=1. N stands for the length of the sequences, therefore here each sequence has 5 elements. What I did was calculate all combinations of sequences 11111,11112,11113.... up to K,K,K,K,K . K stands for the maximum number for each element. After finding all combinations I split each one to sets where each set would be 1+L, 1+L+L.... or 5-L,5-L-L.. Here L is 1 so sets for this sequence (1,2,3,4,5,8,7,6,4,3,2,1) this sequence is more than 5 but just to explain it. Sets would be 1,2,3,4,5,8 8,7,6 4,3,2,1, So we have 3 sets for this sequence. M is 3 so it would be a match. M stands for the number of sets in each sequence. :)

- raiden4589 March 23, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

I have tweak the code a bit

package com.algorithms;

import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;

public class GoogleSequence {

	public class Seq {

		private LinkedList<LinkedList<Integer>> sets;

		public LinkedList<LinkedList<Integer>> getSets() {
			return sets;
		}

		public Seq(LinkedList<LinkedList<Integer>> sets) {
			this.sets = sets;
		}

		@Override
		public String toString() {
			// TODO Auto-generated method stub
			return sets.toString();
		}
	}

	public LinkedList<Seq> calculate(int N, int M, int K, int L) {
		// pos seq of N
		// with M runs
		// nums in seq <= K
		// adj diff <=L

		LinkedList<LinkedList<Integer>> lists = new LinkedList<LinkedList<Integer>>();

		// Get all combinations of sequnces up to N
		for (int j = 0; j < N; j++) {
			int size = lists.size();

			// If lists is empty add the first up to K numbers
			if (size == 0) {
				for (int i = 1; i <= K; i++) {
					LinkedList<Integer> newL = new LinkedList<Integer>();
					newL.add(i);
					lists.add(newL);
				}
			}

			LinkedList<Integer> list = null;

			// Iterate up to the current size of the list.
			// Add up to K to the end of each sublist
			// The iterations follow this pattern,
			// 1,2,3,4,... K
			// 11,21,31,41,12,22,...,13,23.....K1
			for (int s = 0; s < size; s++) {
				list = lists.get(s);
				LinkedList<Integer> newL = new LinkedList<Integer>(list);
				for (int i = 1; i <= K; i++) {
					LinkedList<Integer> temp = new LinkedList<Integer>();
					if (i == 1) {
						list.offerLast(i);
					} else {
						temp.addAll(newL);
						temp.offerLast(i);
						lists.offerLast(temp);
					}
				}
			}

		}

		LinkedList<Integer> pk = lists.peekLast();
		LinkedList<Seq> finalLists = new LinkedList<Seq>();

		for (LinkedList<Integer> list : lists) {
			
			
			int index = 0;
			LinkedList<LinkedList<Integer>> sets = new LinkedList<LinkedList<Integer>>();
			
			while (list.size() > 0 && (index + 1) < list.size()) {
				
				int prev = list.get(index);
				int next = list.get(index + 1);

				
				//Check if pattern exists , if it doesnt then add the new set
				if (prev + L != next && prev - L != next) {
					List<Integer> sub = list.subList(0, index + 2);
					sets.add(new LinkedList<Integer>(sub));
					
					if (list.size() >= index+1) {
						
						list = new LinkedList<Integer>(list.subList(index+1 ,
								list.size()));
						index = 0;
						if (list.size()==1) {
							sets.add(new LinkedList<>(list));
						}
					}
					
				} else {
					
					index++;
					if (index + 1 == list.size() || list.size()==1) {
						sets.add(new LinkedList<>(list));
					}
				}

			}
			
			if (sets.size() == M) {
				finalLists.add(new Seq(new LinkedList<LinkedList<Integer>>(sets)));
			}
		}

		return finalLists;
	}

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		GoogleSequence seq = new GoogleSequence();
		System.out.println("Type four numbers, N M K L");
		LinkedList<Seq> lists = seq.calculate(sc.nextInt(), sc.nextInt(),
				sc.nextInt(), sc.nextInt());
		System.out.println("POSSIBLE:" + lists.size());

		for (Seq linkedList : lists) {
			System.out.println(linkedList.toString());
		}

	}
}

- raiden4589 March 23, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

public class SequenceResult
        {
            public enum SortType
            {
                ASC,
                DESC
            }

            public List<int> Sequence = new List<int>();
            public SortType Sort { get; set; }

        }


        public List<SequenceResult> SegmentArray(int[] input)
        {
            List<SequenceResult> result = new List<SequenceResult>();

            if (input == null || input.Length <2)
            {
                throw new ArgumentException();
            }

            SequenceResult segment = new SequenceResult();
            segment.Sequence.Add(input[0]);
            segment.Sequence.Add(input[1]);
            result.Add(segment);

            if (input[1] > input[0])
            {
                segment.Sort = SequenceResult.SortType.ASC;
            }
            else
            {
                segment.Sort = SequenceResult.SortType.DESC;
            }

            for (int i = 2; i < input.Length; i++)
            {
                SequenceResult.SortType sort = input[i] > input[i - 1] ? SequenceResult.SortType.ASC : SequenceResult.SortType.DESC;

                if (sort == segment.Sort)
                {
                    segment.Sequence.Add(input[i]);
                }
                else
                {
                    segment = new SequenceResult();
                    segment.Sort = sort;
                    segment.Sequence.Add(input[i - 1]);
                    segment.Sequence.Add(input[i]);
                    result.Add(segment);
                }
            }

            return result; 
        }

Test:
[TestMethod()]
public void SegmentArrayTest()
{
Google1 target = new Google1();
int[] input = { 1, 2, 3, 4, 7, 6, 5, 2, 3, 4, 1, 2 };

List<Google1.SequenceResult> actual;
actual = target.SegmentArray(input);

actual.ForEach(m => {
Console.Write(m.Sort + "{");
m.Sequence.ForEach(n =>
{
Console.Write(n + " ");
});
Console.Write("}\r\n");
});
}

Result:
ASC{1 2 3 4 7 }
DESC{7 6 5 2 }
ASC{2 3 4 }
DESC{4 1 }
ASC{1 2 }

- Quan Li April 29, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

This is a tested code in C++:

static int seqRun (int N, int M, int K, int L)
	{
		int result = 0;
		for (int i = 1; i <= K; i++)
		{
			vector<int> seq;
			seq.push_back(i);
			result += seqRun(N,M,K,L,0,-1,seq);
		}
		return result;
	}
	static int seqRun (int N, int M, int K, int L, int run, int direct, vector<int> seq)
	{
		int seq_len = seq.size();
		if (run > M)
			return 0;
		if (seq_len == N)
		{
			if (run < M)
				return 0;
			for (int i = 0; i < N; i++)
				cout << seq[i] << ' ';
			cout << endl;
			return 1;
		}
		int result = 0;
		int last_val = seq.back();
		for (int i = last_val-L; i < last_val; i++)
		{
			if (i > 0)
			{
				vector<int> seq2 = seq;
				seq2.push_back(i);
				if (direct == 0)
				{
					result += seqRun(N,M,K,L,run,0,seq2);
				}
				else
				{
					result += seqRun(N,M,K,L,run+1,0,seq2);
				}
			}
		}
		for (int i = last_val+1; i <= last_val+L; i++)
		{
			if (i <= K)
			{
				vector<int> seq2 = seq;
				seq2.push_back(i);
				if (direct == 1)
				{
					result += seqRun(N,M,K,L,run,1,seq2);
				}
				else
				{
					result += seqRun(N,M,K,L,run+1,1,seq2);
				}
			}
		}
		vector<int> seq2 = seq;
		seq2.push_back(last_val);
		result += seqRun(N,M,K,L,run,-1,seq2);

		return result;
	}

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

1) Do some pre-processing. For any sequence with N elements, split it into multiple continuous sub sequences:

1.1) Iterate all the elements in the seq, if it is > K, split the seq into two sub sequences that is separated by this element. For example, if K = 4, {1,2,3,4,7,2,3,4,1,2} will become {1,2,3,4}, {2,3,4,1,2} since 7 > 4 and it cannot be a continuous part of the sequence according to the problem description.

1.2) Iterate all sequences in step 1.1, and calculate the difference between adjacent elements, if the difference is > L, split the sequence into two sub sequences. For example, if L=2, {2,3,4,1,2} will become {2,3,4}, {1,2} since 4-1=3>2

After pre-processing, the remaining sequences will satisfy the requirement for K and L. The problem is turned into calculating the total number of runs for all these sequences. If the total number of runs is equal to M, the raw sequence is okay and should be counted.

2) To calculate every run of a subsequence after pre-processing, it is quite simple. I will use an example to illustrate it. Only increasing run will be shown here, and decreasing run can be figured out with the same method. Just compare the number with its previous one, and keep tracking from the first number if it is increasing, if in position i, there is one element is decreasing, start a new run from i+1. For sequence {1 2 3 2 6 4}, you will get several runs {1,2,3}, {2,6}, {4}.

I am not completely sure if a run like {1,2,3} should be counted multiple times because it contains {1}, {2}, {3}, {1,2}, {2,3}, {1,2,3} essentially. If it is needed, it can be calculated easily with some combination formula.

3) Sum all the number of runs to see if it is equal to M.

- nybon July 30, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 3 vote

Use the wiki/Longest_increasing_subsequence algorithm
Change the condition of increasing to increasing or decreasing..

- Ayush March 19, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

the question is not to find the longest sub-sequence. The question is to calculate ALL possible sequences of N elements having the described property.

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

The question is not about Long4est increasing subseq, yes, but we will have to find LCS as the question says:
"Count the number of POSSIBLE SEQUENCES of N numbers "
So we will have to find all possible subsequences by using LCS.

- SteveJobs September 02, 2012 | Flag
Comment hidden because of low score. Click to expand.
-1
of 1 vote

Using DP may solve this problem.

- Cheergo September 14, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

why do we need dynamic programming or longets increasing subsequence. as it is either conitnuously increasing or decreasing we can use brute force approach to check continuous numbers and find the sequence.

- Rohit Saraf December 20, 2012 | Flag Reply


Add a Comment
Name:

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

Books

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

Learn More

Videos

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

Learn More

Resume Review

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

Learn More

Mock Interviews

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

Learn More