Amazon Interview Question for Software Engineer in Tests SDE1s


Country: India
Interview Type: In-Person




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

Go to the middle and reverse the second part of the linked list
Now we have 2 pointers one pointing to the first element and the other to the middle element. Compare and return true if pallindrome

- DashDash May 14, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

You will also have to take care for the situation when the LL size is even. In that case, there is no middle element per se, so the range to be reversed are the elements [ n/2 ; n-1 ], where "n" is the size of LL.

0  1  2  3  4  5
a->b->c->c->b->a  // original LL
a->b->c->a->b->c  // reversed at mid-point LL

- ashot madatyan May 15, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

reversing the 2nd part can be confusing incase length of word is odd, eg: bob

an alter-net approach:

use pointer1 in the start(right). use pointer2 at the end(left). pointer1 moves right to left, pointer2 moves left to right. at any point if the pointer value if don't match its not a palindrome. this check must be done unless the pointer are pointing to same character or consecutive. n/2(even length) or n/2+1(oddlength)

- Prithvi May 15, 2013 | Flag
Comment hidden because of low score. Click to expand.
1
of 1 vote

@ the person above, linked list is one direction, not 2. You are thinking about double linked list.

- Mo Lam May 15, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Great idea, but remember to return the linked list back because you may need to use it in the further.

- Mo Lam May 15, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Stack can solve this problem, but as we can't use extra memory, we can still use recursion to simulate stack. size()/2 stacks is ok.

- denghui01 May 16, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

By the way, how will we go to the middle of the linked list, we are not given the size of the linked list. Of course we can use an extra pointer to start traverse till the end, find its length and then goto middle. But, we are not supposed to use any extra memory.

- chaitanya.jun12 May 21, 2013 | Flag
Comment hidden because of low score. Click to expand.
2
of 2 vote

1) Use the two pointer method till first points to middle and second points to end (both even and odd lists should be handled)
2) Reverse the list from head till middle
3) Compare both the lists and report true or false
4) Reverse the first half again and revert the list to its original form

- arun_lisieux May 31, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

You can simplify this by
1. Find the mid point by using the slow and fast runners and then push the first half to the list to a stack from the slow runner. Note that, at this point slow runner is pointing the middle of the linked list and the elements in the stack are in the reverse order.

2. Iterate from the middle to the end of the list with slow pointer and compare the top of the the stack at each iteration. If they don't match return false.

If you can't use extra storage, then you can solve this recursively:

bool isPalindrome(Node** left, Node* right) {
	if (!right) return true;
   
   	bool ispal = isPalindrome(left, right->next);
   	if (ispal == false) return false;
 
   	// check if the values are the same
   	ispal = (right->data == (*left)->data);
 
   	// go to next
   	*left = (*left)->next;
 
   	return ispal;
}

Call this function like:

bool isp = isPalindrome(&head, head);

- oOZz May 31, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

@oOZz: Could you please explain me how will this work in case of odd number of nodes?

- Darshan May 31, 2013 | Flag
Comment hidden because of low score. Click to expand.
2
of 2 votes

@oOZz: Using a stack to compare the elements will work. This might work faster as you can store the nodes in the stack as you slide the slow runner. You dont need the extra traversals reverse the list and revert it back. But this uses n/2 extra space. Decent solution if extra space is not a concern.

- arun_lisieux June 01, 2013 | Flag
Comment hidden because of low score. Click to expand.
1
of 3 vote

The basic idea is to use recursion. We need to have the notion of a 'mirrorNode' to solve this problem. For ex: the last node is the mirror node of the first, the second last is the mirror node of the second and so on. Based on this idea, a simple recursive trick like the below does the job.

A stack cannot be used for this problem as it will take extra memory.

Full java implementation is below.

package org.murali.algos;
import java.util.Scanner;
import java.util.regex.Pattern;

public class LinkedListCareerCup {

	class NodeCareerCup {
		Object val;
		NodeCareerCup next;
		
		public NodeCareerCup(Object val, NodeCareerCup next) {
			super();
			this.val = val;
			this.next = next;
		}
		
	}
		NodeCareerCup head = null;
		
		public boolean CheckIfPalindrom() {
			if (head == null || head.next == null) {
				return true;
			}
			
			NodeCareerCup retNode = checkPalindromeRec(head, head);
			return retNode != null;
		}
		
		public NodeCareerCup checkPalindromeRec(NodeCareerCup current, NodeCareerCup head) {
			
			// last node
			if (current.next == null) {
				if (current.val.equals(head.val)) {
					return head.next;
				} else {
					return null;
				}
			}
			else {
				NodeCareerCup mirrorNode = checkPalindromeRec(current.next, head);
						
				if (mirrorNode != null) {
					if (mirrorNode.val.equals(current.val)) {
						if (mirrorNode.next == null) {
							return head;
						}
						return mirrorNode.next;
					}
					else {
						return null;
					}
				} 
				return null;
			}
		}
		
		public void AddNode(NodeCareerCup node) {
			node.next = head;
			head = node;
		}
		
		
		public static void main(String[] args) {
			LinkedListCareerCup ll = new LinkedListCareerCup();
			
			Pattern pattern = Pattern.compile(System.getProperty("line.separator") + "|\\s");		
			Scanner scanner = new Scanner(System.in);
			scanner.useDelimiter(pattern);
			System.out.println("/////////////////////////////////////");
			System.out.println("Enter numbers with spaces in-between and hit enter twice. For ex:");
			System.out.println("1 2 3 3 2 1\n");
			System.out.println("");
			System.out.println("/////////////////////////////////////\n");
			int i;
			while (scanner.hasNextInt()) {
				i = scanner.nextInt();
				ll.AddNode(ll.new NodeCareerCup(new Integer(i), null));
			}
			System.out.println("That the given list is a palindrome is " + ll.CheckIfPalindrom());
			
		}		
}

- Murali Mohan May 18, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

can you please provide concrete solution

- chetan12189 May 14, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Do you want me to code for the solution? I think once an algorithm of a problem is known, coding may no be a problem.
Please do let me know if you are finding anything wrong with the above solution, we can discuss.
Also let me know if you want concrete code, I will write it down for you

- DashDash May 14, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

yes i was in search of solution

- chetan12189 May 14, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

// some C/C++ style pseudo code
// needs some validations such as check for invalid pointers and etc..

{{
node* reverse_linked_list( node * head)
{
if (head== NULL || head->next==NULL)
{
return head;
}
node *new_head = reverse_linked_list(head->next);
head->next->next = head;
head->next = NULL;
return new_head;
}
Node * MiddleOfList(Node *head)
{
node * middle ;
node * temp = head;
while(temp ->next!=NULL)
{
temp =temp ->next->next
middle = middle->next
}

return middle;
}
BOOL palindrome (Node *head)
{
Node *middle = MiddleOfList(head) ;
head = reverse_linked_list(middle)

while (middle ->next != NULL)
{
if (middle->data == head->data )
continue;
else return false ;
}
return true
}

}}

- SDguy May 14, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

if modifying is not an option, use stack

- bbarodia May 14, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

There's a memory restriction.

- bunnybare May 15, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

an alter-net approach:

use pointer1 in the start(right). use pointer2 at the end(left). pointer1 moves right to left, pointer2 moves left to right. at any point if the pointer value if don't match its not a palindrome. this check must be done unless the pointer are pointing to same character or consecutive. n/2(even length) or n/2+1(oddlength)

- Prithvi May 15, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

What a crazy fellow u are? Do you think it is possible to traverse both ways in a linked list? Or are u assuming a Doubly-Linked List?

- hellohibye May 15, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

oops... the question clearly tells its not a Doubly-linked list. Stupid me.

- Prithvi May 18, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

there's a recursive approach to this

bool isPalindrome ( Node* head, Node*& compare, Node* localNext )
{
    if ( NULL == localNext )
    {
        return true;
    }
    else if ( NULL != localNext->next && head == compare )
    {
        //Still looping
        return isPalindrome ( head, compare, localNext->next );
    }

    if ( compare->data != localNext->data )
    {

       return false;
    }
    else
    {
        compare = compare->next;
        return true;
    }

}

- daylighter May 16, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

given singly linked list
how you find number of nodes and middle of the node
example 1->2->3->4->5->4->3->2->1

- kalai May 16, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

If n is length of linked list, upper bound of n/2. In odd case, you have to ignore n/2 +1 and in even case, you should not.

- Anonymous May 18, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

you can use chasing pointers to get the number of nodes and the middle node in least number of operations.

- peechus June 12, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

if there is a limitation on extra memory then Node temp, and data compare would need to be passed to the isPalindrome class.

public boolean isPalindrome(Node head, Node temp, char compare){

while(head != null){ 
   compare = head.data;
   temp = head;
   while(temp.next != null){
    temp = temp.next;
    compare = temp.data;

   }
   temp = null;
   if(!((head.data).equals(compare)){
   return false;
    }
   
   head = head.next;
   
}
return true;
}

- Anonymous May 16, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

if there is a limitation on extra memory then Node temp, and data compare would need to be passed to the isPalindrome class. (i didnt realize that i had not logged in when i posted the solution before)

public boolean isPalindrome(Node head, Node temp, char compare){

while(head != null){ 
   compare = head.data;
   temp = head;
   while(temp.next != null){
    temp = temp.next;
    compare = temp.data;

   }
   temp = null;
   if(!((head.data).equals(compare)){
   return false;
    }
   
   head = head.next;
   
}
return true;
}

- tmsagila May 16, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Use recursion to go to the middle of the linkedlist and then when you reach there, there are two parts, first one keeps reading the node data backwards as part of recursion popping out, while the second pointer keeps going forward - reading the data from next nodes. Keep comparing data for both of these and check whether it is palindrome or not till last. a sample java code snippet is below
strnode_ is the head node which invokes isPalindrome(strnode_) to check for palindrome.

public boolean isPalindrome(Node str)
	{
		if(str!=null){
			if(count<midlen-1)
			{
				count++;
				strnode_ = strnode_.next_;
				getRevChar(str.next_);
			}

			if(isPalindrome){
				if(isOdd){
					strnode_ = strnode_.next_;
					isOdd = false;
				}
				strnode_ = strnode_.next_;
				isPalindrome = str.data_ == strnode_.data_ ? true : false;
				return true;
			}
			else
			{
				return false;
			}
		}
		return false;
	}

- Arvind May 17, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

No need to modify the list.
1- Traverse till middle element.
2- Keep another pointer at first element.
3- Keep matching values on these two pointers till the second pointer reaches end of list. If all matches then palindrome else not.

- tripper May 19, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

you are the closest of the bunch, but your code checks for AckAck instead of AckkcA.

Implement getLength(Node) and a getNth(Node,int) methods
use getNth(head,int) to 'march backwards' from the midpoint.

no recursion or allocation involved.
O(n^2) -- n calls to getNth, which is O(n)

recursive, modifying, or allocating implementations are O(n)

- h May 21, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

The recursive approach breaks the "extra memory" rule. Each recursion pushes another Node reference onto the stack. Given a string of N characters, there will be N/2 levels of recursion, each with a value on the stack. The stack frame will have a value for each parameter passed to the recursive routine, so passing two parameters pushes two Node references per recursion. Also, stack memory is more limited than heap memory.

- dgehring May 20, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

slow = head; fast=head
while(fast->next != null && fast->next->next!=null)
//fast->next = null odd case
//fast->next->next = null even case
{

	fast = fast->next->next;
	slow = slow->next;
}
start = head;
mid = slow -> next;

while(mid!= null)
{
	if(mid.val != start.val)
		return false; // not palindrome

	mid = mid -> next;
	start = start -> next;
}
return true; // palindrome case

- miryalavignesh June 01, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

This solution does not work

- Anonymous June 09, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

#include <stack>
using namespace std;
class Node
{
public:
	char data;
	Node* next;
	Node():next(NULL){}
};
bool findPalindrome(Node* root)
{
	if(!root)
		return false;
	Node* t1=root;
	Node* t2=root;
	stack<char> st;
	bool end=false;
	//bool odd=false;
	while (true)
	{
		if (t1==NULL)
			break;

		if(!end)
		{
			st.push(t1->data);
		}
		else
		{
			char ch = st.top();
			if(t1->data!=ch)
				return false;
			st.pop();
		}
		if(t1)
			t1=t1->next;
		if(t2)
		{
			t2=t2->next;
			if(t2)
				t2=t2->next;
			else
			{
				st.pop();
			}
		}
		if(!t2)
		{
			end=true;
		}
	}
	return true;
}

- sid June 01, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

1> Scan the linked list to get the count of elements(n).
2> Set the middle as floor(n/2).
3> Now maintain a counter and scan the linked list till the middle is reached, While scanning add the elements in a stack.
4> Now move from the middle one element at a time and pop the element from the stack and compare.
5> If mismatch, not a palindrome
6> If matched till the end of the linked list and the stack is empty, then it is palindrome.

- Subhajit June 01, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

I think this can be done in linear time, we keep two pointers: one is slow and the other is fast, slow move forward one step and fast move forward two steps, then when fast is null or fast->next is null, slow points to the middle node of the list, at the same time, we use stack to keep nodes the slow has ever pointed to. Then move to slow to next, and compare the top value of stack with the value slow points to until slow is null or stack is empty. here are my codes:

#include<iostream>
#include<stack>
#include<string>
using namespace std;

typedef struct node_s {
	char val;
	struct node_s* next;
}node_t;

node_t* createList(char* s) {
	node_t* head = NULL;
	node_t* temp = NULL;
	node_t* p = NULL;
	while (*s) {
		p = (node_t*)malloc(sizeof(node_t));
		p->val = *s;
		p->next = NULL;
		if (NULL == head) {
			head = p;
		} else {
			temp->next = p;
		}
		temp = p;
		s++;
	}
	return head;
}

void destroyList(node_t* head) {
	node_t* p = head;
	while (p) {
		head = p->next;
		free(p);
		p = head;
	}
}

bool isPalindrome(node_t* head) {
	stack<node_t*> m_stack;
	node_t* slow = head;
	node_t* fast = head;
	m_stack.push(slow);
	while (fast->next && fast->next->next) {
		slow = slow->next;
		m_stack.push(slow);
		fast = fast->next;
		fast = fast->next;
		if (NULL == fast->next)
			m_stack.pop();
	}
	slow = slow->next;
	node_t* temp = NULL;
	while (slow && !m_stack.empty()) {
		temp = m_stack.top();
		m_stack.pop();
		if (slow->val != temp->val)
			return false;
		slow = slow->next;
	}
	if (slow || !m_stack.empty())
		return false;
	return true;
}

int main(int argc, char* argv[]) {
	char s[] = "12345678987654321";
	node_t* head = createList(s);
	if (isPalindrome(head))
		cout << "yes" << endl;
	else 
		cout << "non" << endl;
	destroyList(head);
	cin.get();
	return 0;
}

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

how about storing the given list in a stack 1 then pop out..store the pop value in another stack 2.. now compare stack1[top]==stack2[top]...increment top value to check next char stored in position 1 and so on..

- saranya July 10, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Traverse the linked list and populate a Hashtable with the data and a count. If the data is present in the Hashtable increment the count, if not set the count as 1. Complexity -- O(n),
where n is the length of the linked list

Using the keySet method of a HashTable, traverse through each key of the Hashtable. Extract the count value of each key using it's get method.

With an if condition check to see
1) If the value is 1 , increment a counter to 1. If (nested if ) the value of the counter is greater than 1 break out of the loop by returning false. [Odd lengthed palindromes]
2) Else if the value != 2, return false
3) Else return true.

- ann.mpaul July 14, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

here is a method in ruby using an array to check if the list is a palindrome

def is_palindrome?
    current = @head
    full_list = []
    while current.next_node != nil
      full_list += [current.value.to_s]
      current = current.next_node
    end
    full_list += [current.value.to_s]
    full_list == full_list.reverse ? true : false
  end

- VinceBarresi August 30, 2015 | 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