Amazon 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

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

public class ManacherLongestPalindromicSubstring{

	public static String 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 Reply
Comment hidden because of low score. Click to expand.
0
of 4 vote

public class NumberOfPalindromes {

	private void countPalindromes(String s) {
		boolean[][] palindromes = buildPalindromeTable(s);
		int count = 0;
		
		for (int i = 0; i < palindromes.length; i++) {
			for (int j = 0; j < palindromes[0].length; j++) {
				if (palindromes[i][j] == true) {
					count++;
				}
			}
		}

		System.out.println(count);
	}

	private boolean[][] buildPalindromeTable(String s) {
		boolean[][] lookUpTable = new boolean[s.length()][s.length()];
		for (int i = 0; i < s.length(); ++i)
			lookUpTable[i][i] = true;
		for (int i = 1; i < s.length(); ++i) {
			int left = i - 1, right = i;
			while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) {
				lookUpTable[left--][right++] = true;
			}
			left = i - 1;
			right = i + 1;
			while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) {
				lookUpTable[left--][right++] = true;
			}
		}
		return lookUpTable;
	}

	public static void main(String[] args) {
		NumberOfPalindromes palindromes = new NumberOfPalindromes();
		palindromes.countPalindromes("abba");
	}
}

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

Disregarding the errors in your code, why do you have a double boolean array? I'm guessing you're trying to keep a table of the start/stop of your palindromes, but this is beyond scope of the question. Additionally, you don't even take advantage of it. Regardless of your intended use and even though it's a small amount of wasted space, it's still wasted space.

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

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

public class ManacerLongestPalindromicSubstring{

	public static String 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.
0
of 0 vote

Modify Manacher's in the obvious way.

(i.e.,  array of struct { int length_longest_centred_here; int num_centred_here; } ).
                                  ^^^^^^^^                           ^^^^^
                                 part of Manac.                   added for this quest

Should work without added complexity in big-O
Haven't checked though.

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

Modify Manacher's in the obvious way.

(i.e.,  array of struct { int length_longest_centred_here; int num_centred_here; } ).
                                  ^^^^^^^^                           ^^^^^
                                 part of Manac.                   added for this quest

Should work without added complexity in big-O
Haven't checked though.

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

(i.e.,  array of 
struct { int length_longest_centred_here; int num_centred_here; } ).
                ^^^^^^^^                           ^^^^^
          part of Manac.                   added for this question

- 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

else if you meet difficulty,
modify the pre-manacher's optimization (i.e., expand from each possible centre) algorithm using the above structure (no need for the "longest_centred_here" you can work straight with num_centred_here.

- 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

hmmm i'm a little confused on definition

what I said above would "include" duplicates if they come from different parts of the string

this is consistent with the definition that leads to the theorem that every string has 2^n substrings

but not consistent with ( 2^n - duplicates)

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

EEk. That should be:

n(n-1)/2 naive definition of total number of substrings

n(n-1)/2 - duplicates for the strict one

in parallel we get these for subsequences

2^n subsequences (naively)

(2^n - duplicates) for the strict variant

It would seem that some algorithms (like the one I suggested above with expansion from different centres) that solve this problem would need to boolean hash/set to handle strict variants of the definition

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

typed it raw so bugs expected
-> Take expand from centre algorithm and add functionality for this problem
-> using nonnaive definition of substrings (with hashing)

Hash/set/whatever <char*> h;  //boolean hash/set
char buf[s.length/2 + 2]; //store centre, rightwards of such substrings
int num=0;
in i, cen;

for(cen=0; cen<s.length; cen++)  //try all centres
{ 
    for(i=0; cen-i>= 0 && cen+i<s.length ; i++ ) { //expand out from cen
        if( s[cen-i]!=s[cen+i] ) break;
        
        buf[i]=s[cen+i]; //increase candidate substring
        buf[i+1]='\0'   
        if( h.exists(buf) ) continue;
        h.insert(buf), num++;
    }
}
return num;

- 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

^^^ Consecutive hash checks within each iteration of inner for loop can be optimized.

Anyways, there are better ideas out there.

- 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

Hash/set/whatever <char*> h;  //boolean hash/set
char buf[s.length/2 + 2]; //store centre, rightwards of such substrings
int num=0;
in i, cen;

for(cen=0; cen<s.length; cen++)  //try all centres
{ 
    //use s[cen] to expand out "odd length" palindromes
    for(i=0; cen-i>= 0 && cen+i<s.length ; i++ ) { //expand out from cen
        if( s[cen-i]!=s[cen+i] ) break;
        
        buf[i]=s[cen+i]; //increase candidate substring
        buf[i+1]='\0'   
        if( h.exists(buf) ) continue;
        h.insert(buf), num++;
    }
    
    //use s[cen] to expand out "even length" palindromes
    for(i=0; cen-i-1>= 0 && cen+i<s.length ; i++ ) { //expand out from cen
        if( s[cen-i-1]!=s[cen+i] ) break;
        
        buf[i]=s[cen+i]; //increase candidate substring
        buf[i+1]='\0'   
        if( h.exists(buf) ) continue;
        h.insert(buf), num++;
    }
}
return num;

Can make both inner for loops above into a single one
But it would be harder to understand/read
Quick/dirty attempt only:

Hash/set/whatever <char*> h;  //boolean hash/set
char buf[2][s.length/2 + 2]; //store centre, rightwards of such substrings

bool valid[2]; //valid[0] for odd length, valid[1] for even
int num=0;
int i, j, cen;

for(cen=0; cen<s.length; cen++)  //try all centres
{ 
    valid[0]=valid[1]=true;
    for(i=0; cen-i>= 0 && cen+i<s.length ; i++ ) { //expand out from cen
        if( s[cen-i]!=s[cen+i] ) valid[0]=false;
        if( cen > 0 && s[cen-i-1]!=s[cen+i] ) valid[1]=false;
        
        for(j=0; j<2; j++)  //j==0 for odd type, ==1 for even type
            if(valid[j]) {
                if( j==1 && cen ==0) break;  //even for cen==0 meaningless
                buf[j][i]=s[cen+i]; //increase candidate substring
                buf[j][i+1]='\0'  
                if( h.exists(buf[j]) ) continue;
                h.insert(buf[j]), num++;
            }
       if(!valid[0] && !valid[1]) break;
    }
}
return num;

Need to learn to compile/test...

- 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 vote

Complexity: O(N^2)
Explanation: Look for odd length palindromes centered at i, look at even length palindromes starting with i as the left character.
Note: not sure why formatting is off.


//O(N^2) implementation

int numPallindromes3(String s) {

int numPallindromesCounter = 0;

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

for (int j = 1; j < s.length()/2; j++) {

if (i - j < 0 || i + j >= s.length()) continue;

String odd1 = s.substring(i-j, i-j+1);
String odd2 = s.substring(i+j, i+j+1);

if (odd1.equals(odd2)) {
numPallindromesCounter++;
System.out.println(s.substring(i-j,i+j+1));
} else
break;

}

for (int k = 1; k < s.length()/2 + 1; k++) {

if (i - k + 1< 0 || i + k >= s.length()) continue;
String even1 = s.substring(i-k+1, i-k+2);
String even2 = s.substring(i+k, i+k+1);

if (even1.equals(even2)) {
numPallindromesCounter++;
System.out.println(s.substring(i-k+1,i+k+1));
} else
break;

}

}


return numPallindromesCounter;
}

- roberto.triviani November 05, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

public static int findNumOfPalindromes(String s) {
//        Find number of palindromes in a string
        if (s == null || s.isEmpty()) {
            return 0;
        } else if (s.length() == 1) {
            return 1;
        } else {
            int res = s.length();
            for (int i = 0; i < s.length() - 1; i++) {
                boolean broke = false;
                int dif = 1;
                while (!broke && i - dif >= 0 && i + dif < s.length()) {
                        if (s.charAt(i - dif) == s.charAt(i + dif)) {
                            res++;
                        } else {
                            broke = true;
                        }
                        dif++;
                }
                if (s.charAt(i) == s.charAt(i + 1)) {
                    dif = 1;
                    broke = false;
                    res++;
                    while (!broke && i - dif >= 0 && i + 1 + dif < s.length()) {
                            if (s.charAt(i - dif) == s.charAt(i + 1 + dif)) {
                                res++;
                            } else {
                                broke = true;
                            }
                        dif++;
                    }
                }
            }
            return res;
        }
    }

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

TIme Complexity O(n2)

public class NumberofPalindromesInString {
	String str = "";
	NumberofPalindromesInString(String str){
		this.str = str;
	}
	
	public void NumberofPalindromesInString(){
		if(str == null || str.length() == 0){
			System.out.println("Number of Plaindromes "+0);
			return;
		}
		
		int len = str.length(), i =0, j=0;
		
		
		boolean[][] s = new boolean[len][len];
		
		for(i =len-1; i >= 0; i--){
			for(j = i; j< len;j++){
				if( i == j){
					s[i][j] = true;
				} else if( j == i+1){
					s[i][j] = (str.charAt(i) == str.charAt(j));
				} else{
					s[i][j] = s[i+1][j-1] && (str.charAt(i) == str.charAt(j));
				}
			}
		}
		int count = 0;
		
		for(i = 0; i< len; i++){
			int k = i;
			for(j =i; j< len;j++){
				if(s[i][j] && j > k)
					k = j;
			}
			count++;
			i = k+1;
		}
		
		System.out.println("Number of Plaindromes "+count);
	}
	
}

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

//Get each word from string and then call another method to know if it is palindrom or not. if it is then increase the count
//Space complexity is O(1) & Processing will be O(M+K) where m is the number of word and k will be number of character.

public int FindNumberOfPalindrom(string s)
        {      
            int _palindromCount = 0;
            string[] words = s.Split(' ');

            foreach (string word in words)
            {
                if (IsPalindrom(word))
                    _palindromCount++;
            }

            return _palindromCount;

        }

        public bool IsPalindrom(string word)
        {
            bool isPalindrom = true;
            for (int i = 0, j = word.Length - 1; i <= word.Length/2; i++, j--)
            {
                if (word[i] != word[j])
                    isPalindrom = false;
            }

            return isPalindrom;
        }

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

What if the string has no spaces? This assumes that each word is the candidate rather than a substring of the given string.

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

no word and sentence in the question

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

O(n^2) algorithm

/*
 * CountingPalindromes.cpp
 *
 *  Created on: Nov 2, 2013
 *
 */

/*
 * Find number of palindromes in a string
 */

#include<iostream>
#include<cstring>
#include<vector>
using namespace std;


vector<string> countPalindromes(string s){
	vector<string> palindromes;
	char * letters = new char[s.length() + 1];
	strcpy(letters,s.c_str());
	int j,k;
	int i = 0;
	for(i = 0;i < s.length();i++){
		j = i - 1;
		k = i + 1;
		while(j >= 0 && k < s.length() && letters[j] == letters[k]){
			palindromes.push_back(s.substr(j,k - j + 1));
			j--;
			k++;
		}
	}
	for(i = 1;i < s.length();i++){
		j = i - 1;
		k = i;
		while(j >= 0 && k < s.length() && letters[j] == letters[k]){
			palindromes.push_back(s.substr(j,k - j + 1));
			j--;
			k++;
		}
	}
	return palindromes;
}

int main(){
	string s;
	cout << "Enter a string:" << endl;
	getline(cin,s);
	cout << "you entered:" << s << endl;
	vector<string> palindromes = countPalindromes(s);
	cout << "Number of palindromes in the given string " << s << ":" << palindromes.size() << endl;
	cout << "The palindromes found are:" << endl;
	vector<string>::iterator itr;
	for(itr = palindromes.begin();itr != palindromes.end();itr++)
		cout << *itr << endl;
	return 0;
}

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

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

int is_parlindromes( char * str, int str_len)
{
int len = str_len;
int i = 0;

for ( i = 0; i < len/2; i ++)
{
if (str[i] == str[len - i - 1])
continue;
else
return 0;
}

return 1;
}

void print_parlindromes (char *str, int len)
{
int i = 0;
for (i = 0; i < len; i ++)
{
printf("%c", *(str+i));
}
printf ("\n");
}

int main (int argc, char *argv[])
{
int num_of_parl = 0;
int i = 0;
int len = 0;
char *pStr = argv[1];

if (argc != 2)
{
printf ("Need Parameter string!\n");
return 1;

}

printf ("Input string:\n%s\n\n", pStr);

len = strlen (pStr);

printf ("Parlindromes:\n");

for (i = 0; i < len; i ++)
{
int j = 0;
int sub_str_len = strlen(pStr + i);

for (j = 2; j <= sub_str_len; j ++)
{
if (is_parlindromes (pStr + i, j))
{
print_parlindromes (pStr + i, j);

num_of_parl ++;
}
}
}

printf ("\nNumber of parlindromes:%d\n", num_of_parl );

return 0;
}
--------------------------
The result of testing.

./parlindromes abcdefedcdef
Input string:
abcdefedcdef

Parlindromes:
cdefedc
defed
efe
fedcdef
edcde
dcd

Number of parlindromes:6

- yuxiaohui78 November 03, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

{{
#include <stdio.h>
#include <string.h>

int is_palindromes( char * str, int str_len)
{
int len = str_len;
int i = 0;

for ( i = 0; i < len/2; i ++)
{
if (str[i] == str[len - i - 1])
continue;
else
return 0;
}

return 1;
}

void print_palindromes (char *str, int len)
{
int i = 0;
for (i = 0; i < len; i ++)
{
printf("%c", *(str+i));
}
printf ("\n");
}

int main (int argc, char *argv[])
{
int num_of_parl = 0;
int i = 0;
int len = 0;
char *pStr = argv[1];

if (argc != 2)
{
printf ("Need Parameter string!\n");
return 1;

}

printf ("Input string:\n%s\n\n", pStr);

len = strlen (pStr);

printf ("Parlindromes:\n");

for (i = 0; i < len; i ++)
{
int j = 0;
int sub_str_len = strlen(pStr + i);

for (j = 2; j <= sub_str_len; j ++)
{
if (is_palindromes (pStr + i, j))
{
print_palindromes (pStr + i, j);

num_of_parl ++;
}
}
}

printf ("\nNumber of palindromes:%d\n", num_of_parl );

return 0;
}

}}

--------------------------
The result of testing.

./parlindromes abcdefedcdef
Input string:
abcdefedcdef

Parlindromes:
cdefedc
defed
efe
fedcdef
edcde
dcd

Number of parlindromes:6

- yuxiaohui78 November 03, 2013 | Flag Reply


Add a Comment
Name:

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

Books

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

Learn More

Videos

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

Learn More

Resume Review

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

Learn More

Mock Interviews

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

Learn More