Linked List Interview Challenges for Major Tech Companies: Amazon, Facebook, Apple, Microsoft
Question 1 : Remove Duplicates
Write a function to remove duplicates from an unsorted linked list. Input 1 -> 2 -> 2 -> 3 -> 4 -> 4 -> 4 -> 5 Output 1 -> 2 -> 3 -> 4 -> 5
class Node:
def __init__(self, value):
self.value = value
self.next = None
class LinkedList:
def __init__(self):
self.head = None
self.tail = None
self.length = 0
def __str__(self):
temp_node = self.head
result = ''
while temp_node is not None:
result += str(node.value)
if temp_node.next is not None:
result += ' -> '
temp_node = temp_node.next
return result
def append(self, value):
new_node = Node(value)
if self.head is None:
self.head = new_node
self.tail = new_node
else:
self.tail.next = new_node
self.tail = new_node
self.length += 1
def remove_duplicates(ll):
# TODO
Answer : We will assign a pointer that will traverse through the linked list. The we will check if the next node is same as the pointer node or not. If yes, we update the pointer nodes next reference to next node's next node. If not, we simply traverse. At the end, we make a prev node and update the tail to the prev node.
from linkedlist import LinkedList
def remove_duplicates(ll):
# TODO
if ll.head is None:
return
current_node = ll.self #will be used to traverse the list.
prev_node = None #used to keep track of the node before current_node
while current_node:
runner = current_node
while runner.next:
if runner.next.value == current_node.value :
runner.next = runner.next.next
else:
runner = runner.next
prev_node = current_node
current_node = current_node.next
ll.tail = prev_node
runner = current_node
- Inside the while loop,runner
is set to thecurrent_node
.runner
will be used to look ahead in the list for duplicates.while runner.next:
- This is a nested while loop that runs as long asrunner.next
is notNone
. This loop is used to check for duplicates ofcurrent_node
's value in the remaining list.if runner.next.value == current_node.value:
- This is a condition to check if the next value in the list (afterrunner
) is the same as the value ofcurrent_node
.prev_node = current_node
- After we have checked all the remaining list for duplicates ofcurrent_node
, we setprev_node
tocurrent_node
current_node = current_node.next
- We movecurrent_node
one step forward in the list.ll.tail = prev_node
- After the outer while loop ends (meaning we have traversed the entire list),prev_node
is the last node in the list. We setll.tail
toprev_node
, effectively updating the tail of the LinkedList.
The time and space complexity
Time : Since the function has a nested loop that, in the worst case, runs for N^2 iterations, the overall time complexity is O(N^2), where N is the number of nodes in the LinkedList.
Space : O(1)
Question 2 : Return nth to last
If n is 3, we need to return the 3rd element to the last node. The logic here is, we make two pointer and set them to head. Our code will take two params - list, and n.
def nthToLast(li, n):
pointer1 = li.head
pointer2 = li.head
for i in range(n):
if pointer2 is None:
return None
pointer2 = pointer2.next
while pointer2:
pointer1 = pointer1.next
pointer2 = pointer2.next
return pointer 1
Time complexity: O(N), Space complexity : O(1)
Question 3 : Partition
Write a code to partition a linked list around a value x, such that all nodes less than x come before all nodes greater than or equal to x.
from LinkedList import LinkedList
def partition(li,x):
current_node = li.head
li.tail = li.head
while current_node:
nextNode = current_node.next
if current_node.value <= x:
current_node.next = li.head
li.head = current_node
else:
li.tail.next = current_node
li.tail = current_node
current_node = current_node.next
if li.tail.next is not None:
li.tail.next = None
Time complexity: O(N), Space complexity : O(1)
Question 4 : Sum Lists
you have two numbers represented by a linked list, where each node contains a single digit. The digits are stored in reverse order, 1's digit is at the head of the list. Write a function that adds two numbers and returns the sum as a linked list.
Code:
from LinkedList mport LinkedList
def sumList(liA, liB):
n1 = liA.head
n2 = liB.head
carry = 0
li = LinkedList()
while n1 or n2:
result = carry
if n1:
result += n1.value
n1 = n1.next
if n2:
result += n2.value
n2 = n2.next
li.add(int(result % 10))
carry = result / 10
return li
Time complexity: O(N), Space complexity : O(N), because here we are creating another LinkedList.