Understand
Given a sorted linked list, delete all duplicates such that each element appear only once.
- Is that guaranteed elements are sorted?
- Yes
- Is that guaranteed the list has duplicates?
- No
- What should the function return?
- head with each element appears only once.
- Can elements be all integers, negative or any invalid input?
- length can be between 0 to 100, all positive integers.
- Is there any time or space complexity?
- No worries now.
input: [1->2->3->3>4] ==> [1->2->3->4]
input: [1->2->3->4] ==> [1->2->3->4]
input: [] ==> []
Match
- Two pointer approach
Plan
- assign current pointer to head
- loop through each element and assign current to current.next:
- in the loop, create another loop to check if current element's value and current element's next value are equal: * if so, assign current element's next to current next next
- update current to current next
- return head Implement
def deleteDuplicates(head):
current = head
while current:
while current.next and current.next.val == current.val:
current.next = current.next.next
current = current.next
return head
Review
Evaluate
- Time complexity O(n)
- Space complexity O(1)
Given a linked list, determine if it has a cycle in it. For simplicity, assume the linked list cannot have more than 1000 nodes in it.
Understand
- Is that guaranteed that list has a cycle?
- No
- What should the function return?
- Boolean: true if it has a cycle, otherwise false
- Can the list be empty? Yes, length can be between 0 to 100
- Is there any time or space complexity?
- no worries now
input: [1->2=>3->4->5=>] k => 3 ==> True
input: [1->2->3->4->5] k => None ==> False
input: [] ==> False
Match
- Two pointer approach (slow and fast pointers)
Plan
- assign slow and fast pointers to head
- check fast and fast next elements are not None
- loop though in this condition:
- increment slow pointer by one node and fast pointer by two nodes at a time
- check if slow and fast pointers are equal, if so return True
- return False if loop ends without returning True
- loop though in this condition:
Implement
def hasCycle(head):
slow, fast = head, head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if slow == fast:
return True
return False
Review
Evaluate
- Time complexity O(n)
- Space complexity O(1)
Merge two sorted linked lists.
Understand
- Is that guaranteed elements are sorted?
- Yes
- Can either input be empty?
- Yes
- Can length of inputs not be equal?
- Yes, append leftover to the tail if either of input has more nodes
- Can the node values be negative?
- Yes. The node values will fall between -100 and 100.
- Can we create new nodes?
- No. The question asks you to splice the given nodes.
- Is there any time or space complexity?
- no worries now but can you solve it with constant space
input: [1->2->3], [2->4] ==> [1->2->2->3->4]
input: [1->2->3], [] ==> [1->2->3]
Match
- Two pointer approach (tail)
- Dummy head
Plan
- create dummy head from a new List Node
- assign tail to dummy head so we can add elements from list1 and list2
- in while loop, check list1 and list2 are not None:
- if list1' element val is less than list2's element val:
- assign list1 to tail next
- increment list1 by one node
- else:
- assign list2 to tail next
- increment list2 by one node
- assign tail to tail next so it moves forward till either list1 or list2 reaches its end and return None in while loop.
- if list1' element val is less than list2's element val:
- after loop ends and if there is any leftover in either list1 or list2, check list1 in not None:
- assign leftover list1 elements to tail next
- else if list2 has leftover elements: assign leftover list2 elements to tail next
- return dummy next
Implement
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def mergeTwoLists(list1, list2):
dummy = ListNode()
tail = dummy
while list1 and list2:
if list1.val < list2.val:
tail.next = list1
list1 = list1.next
else:
tail.next = list2
list2 = list2.next
tail = tail.next
if list1:
tail.next = list1
elif list2:
tail.next = list2
return dummy.next
Review
Evaluate
- time complexity O(n) not sure because we loop through till n and still have to deal with leftover. Is assigning leftover to tail's next node constant time?
- space complexity O(n)not sure because we loop through till n and still have to deal with leftover. Is assigning leftover to tail's next node constant space?
Given a linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list. Can you do it without taking up extra memory?
Understand
- Is that guaranteed the list has duplicates? No
- What should the function return?
- linked list with distinct numbers
- What are nodes values? Integer, string, positive or negative numbers?
- -100 <= Node.val <= 100
- Is the list sorted?
- Yes, the list is guaranteed to be sorted in ascending order.
- Is there any time or space complexity?
- Yes, can you do it without taking up extra memory?
- Can the input list be empty?
- No. Assume the input list will have anywhere from 1 node to 30000 nodes.
input: 1->2->3->3->4->4->5 ==> 1->2->5
Input: 1->1->1->2->3 ==> 2->3
Input: 5->6->3->5 ==> 6->3 or 3->6
Match
- dummy head approach
- two pointer approach (prev and current)
Plan
- create a dummy head from a new List Node (0, head)
- assign prev pointer to dummy head
- loop though each node till it reaches its end:
- check current next is not None and current node's value is equal to next node's value:
- if so, loop though to skip and assign current node to next node
- update prev node to current next node
- else: update prev node to prev next node
- update current node to current next node
- check current next is not None and current node's value is equal to next node's value:
- return dummy next
Implement
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def deleteDuplicates(head):
dummy = ListNode(0, head)
prev = dummy
while head is not None:
if head.next is not None and head.val == head.next.val:
while head.next is not None and head.val == head.next.val:
head= head.next
prev.next = head.next
else:
prev = prev.next
head = head.next
return dummy.next
Review
Evaluate
- time complexity O(n)
- space complexity O(1)