Пример #1
0
 def rotateRight(self, head: ListNode, k: int) -> ListNode:
     """Two pointers.
 """
     s = ListNode(0)
     s.next = head
     if not s.next:
         return s.next
     x, y, i = s, s, 0
     while i < k:
         if y.next:
             y = y.next
         else:
             y = s.next
             k %= i
             if k == 0:
                 k += i * 2
             else:
                 k += i
         i += 1
     while y.next:
         x = x.next
         y = y.next
     if not x == s:
         y.next = s.next
         s.next = x.next
         x.next = None
     return s.next
Пример #2
0
 def plusOne(self, head: ListNode) -> ListNode:
   # sentinel node
   s = ListNode('')
   s.next = head
   # create prev along the way
   node = s
   while node.next:
     node.next.prev = node
     node = node.next
   # plus one on the node from tail
   while True:
     if node.val < 9:
       node.val += 1
       break
     else:
       node.val = 0
       node = node.prev
       if node.val == '':
         x = ListNode(1)
         x.next = node.next
         node.next.prev = x
         node.next = x
         x.prev = node
         break
   return s.next
Пример #3
0
 def swapPairs(self, head: ListNode) -> ListNode:
     s = ListNode(0)
     s.next = head
     x = s
     while x.next and x.next.next:
         z = ListNode(x.next.val)
         x.next = x.next.next
         x = x.next
         z.next = x.next
         x.next = z
         x = x.next
     return s.next
Пример #4
0
 def isPalindrome(self, head: ListNode) -> bool:
     """Two pass, 1st reach to tail and create reverse link along the way, 2nd two pointers head and tail.
   An alternative approach is 1st pass two pointers slow (1 step each iteration) and fast (2 step each iteration),
   and when fast reach to the tail, slow reach to middle, then reverse along the way slow from middle to the tail,
   and then 2nd pass two pointers head and tail and comparison along the way. 
   However, this alternative approach need more caution on corner cases, odd/even middle, empty linked list and etc.
 """
     # 1st pass
     s = ListNode('')
     s.next = head
     prev, node = s, head
     while node:
         node.prev = prev
         prev = node
         node = node.next
     t = ListNode('')
     prev.next = t
     t.prev = prev
     # 2nd pass
     x, y = s.next, t.prev
     # equality test use x is y (kind like x === y in javascript) instead of x == y, strict for reference equality,
     # because in the config.listnode, class ListNode defined __eq__() as value equal for general purpose equality.
     while not (x is y or x.prev is y):
         if not x.val == y.val:
             return False
         else:
             x = x.next
             y = y.prev
     return True
Пример #5
0
 def reverseList(self, head: ListNode) -> ListNode:
     """Iterative Solver 1.
 """
     s = ListNode(0)
     s.next = head
     if s.next and s.next.next:
         x = s.next
         y = s.next.next
         while y:
             h = s.next
             z = y.next
             s.next = y
             y.next = h
             x.next = z
             y = x.next
     return s.next
Пример #6
0
 def reorderList(self, head: ListNode) -> None:
     """Do not return anything, modify head in-place instead.
 """
     s = ListNode('')
     s.next = head
     # step 1: reverse the 2nd half of the linked list: 1->2->3->4->5 to 1->2->3<-4<-5
     x = y = s
     while y:
         x = x.next
         y = y.next
         if y:
             y = y.next
     # x is the middle one, reverse from x to ende
     prev, curr = None, x
     while curr:
         hold = curr.next
         curr.next = prev
         prev = curr
         curr = hold
     # step 2: two pointers from init and ende to switch 1(x)->2->3<-4<-5(y) to 1->5->2(x)->3<-4(y) to 1->5->2->4->3
     x, y = head, prev
     while not (x == y or x.next == y):
         # hold of x.next and y.next
         u, v = x.next, y.next
         x.next = y
         y.next = u
         x, y = u, v
     return None
Пример #7
0
 def reverseBetween(self, head: ListNode, m: int, n: int) -> ListNode:
     if m == n: return head
     s = ListNode('')
     s.next = head
     i = 0
     x = y = z = s
     while i < m - 1:
         x = x.next
         y = y.next
         z = z.next
         i += 1
     y = y.next
     z = z.next
     i += 1
     p = x
     while i < n:
         q = z.next
         z.next = p
         p = z
         z = q
         i += 1
     x.next = z
     y.next = z.next
     z.next = p
     return s.next
 def deleteNode(self, node: ListNode) -> None:
     """Do not return anything, modify node in-place instead.
   Key: O(1), move the value of node.next, and link from node to node.next.next.
   The key is since we don't have prev, we modify this node as prev and instead delete node.next as node.
 """
     node.val = node.next.val
     node.next = node.next.next
 def deleteNode(self, node: ListNode) -> None:
     """Do not return anything, modify node in-place instead.
   Key: O(N), move the value one by one while traverse from node to tail.
 """
     while node.next.next:
         node.val = node.next.val
         node = node.next
     node.val = node.next.val
     node.next = None
Пример #10
0
 def reverseList(self, head: ListNode) -> ListNode:
     """Recursive Solver.
 """
     if head and head.next:
         x = self.reverseList(head.next)
         head.next.next = head
         head.next = None
         return x
     else:
         return head
Пример #11
0
 def deleteDuplicates(self, head: ListNode) -> ListNode:
     s = ListNode(0)
     s.next = head
     x = y = head
     while y and y.next:
         y = y.next
         if x.val < y.val:
             x.next = y
             x = x.next
     if x and x.next:
         x.next = None
     return s.next
Пример #12
0
 def deleteDuplicates(self, head: ListNode) -> ListNode:
   s = ListNode('')
   s.next = head
   x = y = s
   while y and y.next:
     while y.next and y.val == y.next.val:
       y = y.next  
     y = y.next
     if (not y) or (not y.next) or (not y.val == y.next.val):
       x.next = y
       x = x.next
   return s.next
Пример #13
0
 def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
     s = ListNode(0)
     s.next = head
     x = s
     z = s
     for i in range(n):
         x = x.next
     while x.next:
         x = x.next
         z = z.next
     z.next = z.next.next
     return s.next
Пример #14
0
 def removeElements(self, head: ListNode, val: int) -> ListNode:
     s = ListNode('')
     s.next = head
     prev, node = s, head
     while node:
         if node.val == val:
             # skip node, hold prev
             prev.next = node.next
         else:
             # move prev to forward
             prev = node
         node = node.next
     return s.next
Пример #15
0
 def sortList(self, head: ListNode) -> ListNode:
     """merge sort on linked list.
   iterate over linked list, say, s -> head -> ...-> ..
   k: number of every k nodes are sorted, k = 1, 2, .. n, e.g., s -> l -> .. -> x -> .. -> y -> .. -> r -> .. 
                                                                               ---------  ---------
                                                                                k nodes    k nodes
   merge k nodes from x and y, so every 2k nodes are sorted, l and r are the left and right node for next x, y pair
 """
     s = ListNode('')
     s.next = head
     # linked list length
     # it is ok to get n from k = 1 case, but this way is more cleaner
     x, n = s, 0
     while x.next:
         x = x.next
         n += 1
     # merge sort
     k = 1
     while k < n:
         l = s
         while l.next:
             x = l.next
             # move k step forward, break link so x -> ... -> None, with lengh k
             y = x
             for _ in range(k - 1):
                 if y is not None:
                     y = y.next
             if y is not None:
                 h = y
                 y = y.next
                 h.next = None
             # move k step forward, break link so y -> ... -> None, with lengh k
             r = y
             for _ in range(k - 1):
                 if r is not None:
                     r = r.next
             if r is not None:
                 h = r
                 r = r.next
                 h.next = None
             # merge and connect, so that l -> mergeSorted(x, y) -> r
             if y is not None and not x == y:
                 l = self.merge(l, x, y, r)
             else:
                 break
         k *= 2
     return s.next
 def deleteNodes(self, head: ListNode, m: int, n: int) -> ListNode:
     s = ListNode('')
     s.next = head
     prev, node = s, head
     while node:
         count = 0
         while node and count < m:
             prev, node = node, node.next
             count += 1
         hold = prev
         if count == m:
             count = 0
             while node and count < n:
                 prev, node = node, node.next
                 count += 1
         prev = hold
         # passthrough
         prev.next = node
     return s.next
Пример #17
0
 def insertionSortList(self, head: ListNode) -> ListNode:
     # INTEGER_MIN
     s = ListNode(-2147483648)
     s.next = head
     # insertion sort
     x = head
     while x and x.next:
         y = x.next
         if y.val < x.val:
             z = s
             while not z == x:
                 if y.val < z.next.val:
                     x.next = y.next
                     y.next = z.next
                     z.next = y
                     break
                 z = z.next
         else:
             x = x.next
     return s.next