Intuition
- This question can be solved naively by keeping two arrays, odd and even, to track which nodes are even and odd, making copies of them, then connecting together and having the last odd node’s next equal to the even node list’s beginning.
- To solve in constant space, we follow logic similar to Reverse Linked List which required a dummy node, except we have two dummy nodes.
- In the end, of traversing, depending on if there are an odd or even number of elements, that is the deciding factor of whether to connect the second to last or last node.
- Since if there are an odd number of nodes, the last node’s next node must be connected to the 2nd node from the beginning, and if there are an even number of nodes, it must be connected to the first node from the beginning.
Complexity
Runtime
to traverse through the entire linked list
Space
to in place link the nodes
Code
Constant Space
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def oddEvenList(self, head: Optional[ListNode]) -> Optional[ListNode]:
if not head:
return None
orig_prev, orig_cur = ListNode(-1), ListNode(-1)
orig_prev.next = orig_cur
orig_cur.next = head
prev, cur, itr = orig_prev, orig_cur, head
n = 0
while itr:
n += 1
prev.next = itr
prev = cur
cur.next = itr.next
cur = itr
itr = itr.next
if n % 2 == 0:
prev.next = orig_cur.next
else:
cur.next = orig_cur.next
return orig_prev.nextTruncated
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def oddEvenList(self, head: Optional[ListNode]) -> Optional[ListNode]:
if not head:
return None
orig_prev, orig_cur = ListNode(-1), ListNode(-1)
orig_prev.next, orig_cur.next = orig_cur, head
prev, cur, itr = orig_prev, orig_cur, head
n = 0
while itr:
n += 1
prev.next, prev = itr, cur
cur.next, cur = itr.next, itr
itr = itr.next
if n % 2 == 0:
prev.next = orig_cur.next
else:
cur.next = orig_cur.next
return orig_prev.nextNaive Approach Without Array
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def oddEvenList(self, head: Optional[ListNode]) -> Optional[ListNode]:
if not head:
return None
if not head.next:
return head
odd = ListNode(head.val)
orig_odd = odd
even = ListNode(head.next.val)
orig_even = even
itr = head.next.next
n = 2
while itr:
if n % 2 == 0:
odd.next = ListNode(itr.val)
odd = odd.next
else:
even.next = ListNode(itr.val)
even = even.next
itr = itr.next
n += 1
odd.next = orig_even
return orig_oddNaive Approach
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def oddEvenList(self, head: Optional[ListNode]) -> Optional[ListNode]:
if not head:
return None
odd = []
even = []
itr = head
n = 0
while itr:
if n % 2 == 0:
odd.append(ListNode(itr.val))
else:
even.append(ListNode(itr.val))
n += 1
itr = itr.next
for i in range(1, len(odd)):
odd[i - 1].next = odd[i]
for i in range(1, len(even)):
even[i - 1].next = even[i]
if even:
odd[-1].next = even[0]
return odd[0]Notes
Cards
START Basic Front: Odd Even Linked List Back: Three pointers, two dummies, and keep track of where to connect end to END