Amazon Interview Question for Software Engineer / Developers


Country: United States
Interview Type: Phone Interview




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

Search term: Manacher's algorithm.

O(N).

- S O U N D W A V E November 03, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
2
of 2 votes

Here is an implementation

Use Manacer's algorithm to find them in O(n)

public class ManacerLongestPalindromicSubstring{

	public static String void preprocess(String in){
		StringBuffer sb = new StringBuffer();
			sb.append’#’);
		for(int i=0; i<in.length(); i++){
			sb.append(in.charAt(i));
			sb.append(‘#’);
		}
		return sb.toString();
	}

	public static String LongestPalindrome(String in){

	/*Preprocess the string to insert special character  ‘#’ in the spaced between characters in input and the two outside edges. This is done merely to make the computation identical for both odd and even length input string. */

		String S = preprocess(in);
		int C = 0; //contains center of current palindrome
		int R = 0; //contains the right edge of current palindrome
		int[] P = new int[S.length()];

		// P[i] contains the length of longest palindrome (in S not original in) centered at i

		for(int i=0;i<P.length(); i++) 
			P[i] = 0;
		// for each position find longest palindrome centered at the position, save length in P

		for(int i=0; i<S.length; i++){
			int i_mirror = 2*C-i; // as C - i_mirror = i - C due to symmetric property 
		
			/*When R-i > P[i_mirror] then palindrome at center i_prime contained completely within palindrome centered at C.  Otherwise R-i <= P[i_mirror] means that the palindrome at ceter i_mirror  doesn’t fully contained in the palindrome centered at C. In this case palindrome at i is extendable past R*/

			P[i] = (R>i) ? min(P[i_mirror], R-i) : 0;

			// if palindrome centered at i is extendable past R then extend R to the right edge of newly extended palindrome

			while(S[i+P[i]+1] == S[i-P[i]-1])
				P[i]++;

			// If palindrome centered at i extend past R then update Center to i

			if(i+P[i] > R){
				C = i;
				R = i+P[i];
			}
		}
		return extractLongest(in, P);
	}

	public int extractLongest(String in, int[] P){
		int longestCenter = 0;
		int longestLength = 0;

		for(int i=0; i<P.length; i++){
			if(P[i] > longestLength){
				longestLongest = P[i];
				longestCenter = i;
			}
		}

		return in.substring((longestCenter-longestLength-1)/2, longestLemgth);
	}

	public Set<String> allPalindromicSubstring(String in, int[] P){
		HashSet<String> all = new HashSet<String>();

		for(int i=0; i<P.length;  i++){
			if(P[i] != 0)
				all.add(in.substring((i-P[i]-1)/2, P[i]));
		}	

		return all;
	}
}

- zahidbuet106 December 16, 2013 | Flag
Comment hidden because of low score. Click to expand.
1
of 3 vote

There are 2 ways.

Either use suffix tree.
Use DFS. Remove last and first character of the strings and create 2 other strings and check for palindrome.Keep doing this for all the substring, until the palindrome is found

- Stupid Developer November 02, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Using a suffix tree would be a poor choice for space.

- nothing special here November 02, 2013 | Flag
Comment hidden because of low score. Click to expand.
1
of 1 vote

Yeah thats true...That is the con of Suffix tree....I just suggested 2 ways :)

- Stupid Developer November 02, 2013 | Flag
Comment hidden because of low score. Click to expand.
1
of 1 vote

+1 Suffix tree beats N^2 expand from centre in time.

- S O U N D W A V E November 03, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Actually, I didn't realize that you could get O(n) until I read some paper on it. Yet another cool use of Suffix Trees.

- nothing special here November 03, 2013 | Flag
Comment hidden because of low score. Click to expand.
-1
of 1 vote

no suffix is nlogn

- anon November 04, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 2 vote

Use two index values to traverse over the string as "the middle values" and then use those index values to sprawl outwards from the middle to the end. You could also just get away with one index value. You just need to be aware of even/odd length palindromes.

For example,
a = {d,a,b,b,a,c}

Here you'll check [i,j] = {0,0} and [i,j] = {0,1}.

Now sprawl outwards from these two indexes. For i=0, you're limited to d since i will be less than 0 when you decrement it. For {0,0}, you'll get d and this will be your max palindrome until you get to {a,b,b,a}.

Progressing through the iterations, you'll eventually get something like [i,j] = {2,2} and {2,3}.
For {2,2}, you won't get a valid search. For {2,3}, you'll get {a,b,b,a}. Note, you'll also get {b,b} within your {2,3} search.

This should be O(N^2) time.

- nothing special here November 02, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Nice.

I think this is basically the best way that doesn't require the slickness (i.e. trick) of Manacher's (which is either just "known" or needs "a bit of time to think of").

Manac. is basically an optimization on nothing's alg to cut out some redundancies.

- S O U N D W A V E November 03, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

returns the actual palandrome for which you can just call length

def largestPalandrome (str)
start = 0
finish = str.length -1
length = 0
maxS = 0
maxE = 0
maxL = 0
i = 0
j = 0
found = false

while (start < finish - 1)
if (str[start] == str[start+1])
found = true
i = start
j = start+1
else if (start>0 && str[start-1] = str[start+1])
found = true
i = start - 1
i = start + 1
end

if found
while (i>0 && j<finish && str[i] == str[j])
i--
j++
length += 2
end
if length > maxL
maxL = length
maxS = i
maxE = j
end
i = 0
j = 0
found = false
end
start++
end
return str[maxS, maxE]
end

pal = largestPalandrome(yourString)
pal.length

- Ruby time November 03, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

public class Longest_Palindrome_subsequence {//Using Dynamic Programming and filling //upper half of the diagonal table at the end the table[0][n-1] will give the result

	int lps_DP(char [] str)
	{	int n = str.length;
		int [][] table = new int[n][n] ;
		
		for(int i = 0;i<n;i++)
			table[i][i] = 1;
		
		for(int len = 2;len <=n;len++)
		{
			for(int i = 0;i <n-len+1;i++)
				{
				int j = i + len - 1;
				if(str[i]==str[j] && len ==2)
					table[i][j] = 2;
				else if(str[i]==str[j])
					table[i][j] = table[i+1][j-1]+2;
				else
					table[i][j] =Math.max(table[i][j-1],table[i+1][j]);
				}
			
			
		}
		
		
		return table[0][n-1];
	}
	
}

- RS November 04, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Dynamic programming based solution. This prints the longest palindrome.

/*
 * palindrome: output the longest contiguous palindrome in the
 * input string.
 * 
 * Usage: palindrome string
 */

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


/* bounds of a substring (both indexes inclusive) */
struct bounds {
	int start;
	int end;
};


/*
 * palindrome: Determine the longest contiguous palindrome in
 * the substring starting at index start through index end,
 * both inclusive.  Use dynamic programming (top-down with
 * memoization).
 * 
 * If s[start] == s[end], and s[start+1]..s[end-1] is a
 * palindrome, then the longest palindrome is s[start]..s[end].
 * Otherwise, the longest palindrome is the longer of the
 * longest palindrome in s[start]..s[end-1] and s[start+1]..s[end].
 * Simple cases: every single character string (start == end)
 * is a palindrome.  Empty string is a palindrome.
 * 
 * Return the longest palindrome indexes in b.
 * 
 * Maintain a cache of longest palindrome indexes in pcache.
 */
void
palindrome(const char *s, struct bounds *b, struct bounds *pcache)
{
	assert(s);
	assert(b);
	assert(pcache);
	size_t len = strlen(s);
	assert(b->start >= -1  &&  b->start <= len);
	assert(b->end >= -1  &&  b->end <= len);
	
	int start = b->start, end = b->end;
	
	/*
	 * If start > end, we have an empty string which is a palindrome.
	 * Single character strings are palindromes.
	 */
	if (start >= end)
		return;

	/* is the result already cached? */
	if (pcache[start*len + end].start != -1) {
		*b = pcache[start*len + end];
		return;
	}
	
	/* is the whole substring a palindrome? */
	if (s[start] == s[end]) {
		struct bounds inner = {start+1, end-1};
		palindrome(s, &inner, pcache);
		if (inner.start == start+1  &&  inner.end == end-1) {
			/* s[start]..s[end] is a palindrome */
			pcache[start*len + end] = *b;
			return;
		}
	}
	
	struct bounds inner1 = {start+1, end};
	palindrome(s, &inner1, pcache);
	struct bounds inner2 = {start, end-1};
	palindrome(s, &inner2, pcache);
	int len1 = inner1.end - inner1.start;
	int len2 = inner2.end - inner2.start;
	if (len1 > len2)
		pcache[start*len + end] = *b = inner1;
	else
		pcache[start*len + end] = *b = inner2;
}


/*
 * longest_palindrome: Allocate the cache and then call palindrome to
 * get the longest palindrome.  Finally, free the cache.
 */
void
longest_palindrome(const char *s, struct bounds *b)
{
	assert(s);
	assert(b);
	size_t len = strlen(s);
	assert(b->start == 0);
	assert(b->end == len-1);
	
	struct bounds *pcache = malloc(len * len * sizeof(struct bounds));
	assert(pcache);
	for (int i = 0; i < len; i++)
		for (int j = 0; j < len; j++)
			pcache[i*len + j].start = pcache[i*len + j].end = -1;
		
	palindrome(s, b, pcache);
	
	free(pcache);
}


int
main(int argc, const char *argv[])
{
	if (argc != 2) {
		fprintf(stderr, "Usage: palindrome string\n");
		return 1;
	}
	
	const char *s = argv[1];
	struct bounds b = {0, strlen(s)-1};
	longest_palindrome(s, &b);
	
	printf("Longest palindrome of %s is ", s);
	const int end = b.end;
	for (int i = b.start; i <= end; i++)
		printf("%c", s[i]);
	printf("\n");
	
	return 0;
}

- Event Horizon December 29, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

private static boolean isSubstringPalyndrome(char[] charSeq, int start, int end) {
while(start<end) {
if(charSeq[start] != charSeq[end]) return false;

start++;
end--;
}
return true;
}

private static int findLengthOfMaxLengthPalyndrome(String s) {

char[] stringAsCharSeq = s.toCharArray();

int maxLength = 1;

for(int i = 0; i < stringAsCharSeq.length; i++) {
for(int j = i+maxLength ; j < stringAsCharSeq.length; j++) {
if( isSubstringPalyndrome(stringAsCharSeq, i, j) ) maxLength = j - i + 1;
}
}

return maxLength;

}

- Earth November 02, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Appears this solution's running time is O(n^3) with no palindrome found.

- nothing special here November 02, 2013 | 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