def test_143_reorderList(self): head = ListNode(1) head.next = ListNode(2) head.next.next = ListNode(3) head.next.next.next = ListNode(4) head.next.next.next.next = ListNode(5) self.solution._143_reorderList(head) self.assertEqual(1, head.val) self.assertEqual(5, head.next.val) self.assertEqual(2, head.next.next.val) self.assertEqual(4, head.next.next.next.val) self.assertEqual(3, head.next.next.next.next.val) head = ListNode(1) head.next = ListNode(2) head.next.next = ListNode(3) head.next.next.next = ListNode(4) self.solution._143_reorderList(head) self.assertEqual(1, head.val) self.assertEqual(4, head.next.val) self.assertEqual(2, head.next.next.val) self.assertEqual(3, head.next.next.next.val)
def mergeTwoLists(self, l1, l2): """ :type l1: ListNode :type l2: ListNode :rtype: ListNode """ n1 = ListNode(0) # 优化:先找到小的头节点,可以无需添加dummy节点 n1.next, n2 = l1, l2 head = n1 while n1.next and n2: if n1.next.val <= n2.val: n1 = n1.next else: p = n2 n2 = n2.next p.next = n1.next n1.next = p n1 = n1.next if n2: n1.next = n2 return head.next
def deleteDuplicates1(self, head: ListNode) -> ListNode: # maintain a prev to indict last-previous node of current "while" prev = ListNode() prev.next = head # declare a res head real_head = ListNode() real_head.next = prev # side case if not head or not head.next: return head # maintain a flag to indict that if last while go in the "if head.val == head.next.val". flag = False while head.next: if head.val == head.next.val: head.next = head.next.next flag = True else: if flag: prev.next = head.next head = prev else: prev = head head = head.next flag = False return real_head.next.next
def test_2_addTwoNumbers(self): l1 = ListNode(2) l1.next = ListNode(4) l1.next.next = ListNode(3) l2 = ListNode(5) l2.next = ListNode(6) l2.next.next = ListNode(4) l3 = self.solution._2_addTwoNumbers(l1, l2) self.assertEqual(7, l3.val) self.assertEqual(0, l3.next.val) self.assertEqual(8, l3.next.next.val)
def merge_sort(head: ListNode, length: int) -> Tuple[ListNode, ListNode]: # Sort list for given length, return sorted list and list after length. if not head: return (None, None) if length == 1: next_head = head.next head.next = None return (head, next_head) new_head_1, next_to_sort_1 = merge_sort(head, length // 2) new_head_2, next_to_sort_2 = merge_sort(next_to_sort_1, length // 2 + length % 2) # Merge new_head_1 and new_head_2. p = dummy = ListNode(0) p1, p2 = new_head_1, new_head_2 while p1 or p2: v1 = p1.val if p1 else float('inf') v2 = p2.val if p2 else float('inf') if v1 <= v2: p.next = p1 p1 = p1.next else: p.next = p2 p2 = p2.next p = p.next return (dummy.next, next_to_sort_2)
def deleteDuplicates2(self, head: ListNode) -> ListNode: # side case if not head or not head.next: return head # dummy node: In case of the LinkedList's head maybe deleted. 'dummy.next' will point to new head when origin head was deleted. dummy = ListNode(0) dummy.next = head # 提前想好要用几个辅助变量。本题很明显需要维护当前节点和当前节点的前一个节点一共俩,直接声明变量赋值,不要乱用head,会导致指向混乱。 pre = dummy cur = head # 循环体为cur node节点 while cur: # 碰到cur和cur.next值相等,直接将cur后移,直到不相等 while cur.next and cur.val == cur.next.val: cur = cur.next # 以下是cur和cur.next值不相等的情况(此处方法是用if判断,因为假如没有发生过while cur后移操作的话,pre.next应当是指向cur的;而我自己的方法是增加flag变量,学!) if pre.next == cur: # 没有发生过while cur后移操作:直接将pre后移 pre = pre.next else: # 发生过while cur后移操作:维护pre.next链,pre不用动 pre.next = cur.next cur = cur.next return dummy.next
def swap_pairs(head: ListNode) -> ListNode: """ :type head: ListNode :rtype: ListNode """ # Dummy node acts as the prevNode for the head node # of the list and hence stores pointer to the head node. dummy = ListNode(-1) dummy.next = head prev_node = dummy while head and head.next: # Nodes to be swapped first_node = head second_node = head.next # Swapping prev_node.next = second_node first_node.next = second_node.next second_node.next = first_node # Reinitializing the head and prev_node for next swap prev_node = first_node head = first_node.next # Return the new head node. return dummy.next
def test_142_detectCycle(self): head = ListNode(1) head.next = ListNode(2) head.next.next = ListNode(3) head.next.next.next = ListNode(4) head.next.next.next.next = head.next self.assertEqual(head.next, self.solution._142_detectCycle(head))
def test_21_mergeTwoLists(self): l1 = ListNode(1) l1.next = ListNode(2) l1.next.next = ListNode(3) l2 = ListNode(1) l2.next = ListNode(2) l2.next.next = ListNode(4) head = self.solution._21_mergeTwoLists(l1, l2) self.assertEqual(1, head.val) self.assertEqual(1, head.next.val) self.assertEqual(2, head.next.next.val) self.assertEqual(2, head.next.next.next.val) self.assertEqual(3, head.next.next.next.next.val) self.assertEqual(4, head.next.next.next.next.next.val)
def test_141_hasCycle(self): head = ListNode(0) head.next = ListNode(1) head.next.next = ListNode(2) head.next.next.next = ListNode(3) head.next.next.next.next = head.next self.assertEqual(True, self.solution._141_hasCycle(head))
def test_19_removeNthFromEnd(self): head = ListNode(1) head.next = ListNode(2) head.next.next = ListNode(3) head = self.solution._19_removeNthFromEnd(head, 3) self.assertEqual(2, head.val) self.assertEqual(3, head.next.val)
def test_24_swapPairs(self): head = ListNode(1) head.next = ListNode(2) head.next.next = ListNode(3) head = self.solution._24_swapPairs(head) self.assertEqual(2, head.val) self.assertEqual(1, head.next.val) self.assertEqual(3, head.next.next.val)
def test_82_deleteDuplicates(self): head = ListNode(1) head.next = ListNode(1) head.next.next = ListNode(3) head.next.next.next = ListNode(4) head = self.solution._82_deleteDuplicates(head) self.assertEqual(3, head.val) self.assertEqual(4, head.next.val) self.assertIsNone(head.next.next)
def test_23_mergeKLists(self): head1 = ListNode(1) head1.next = ListNode(2) head1.next.next = ListNode(4) head2 = ListNode(1) head2.next = ListNode(3) head2.next.next = ListNode(4) head3 = ListNode(5) head = self.solution._23_mergeKLists([head1, head2, head3]) self.assertEqual(1, head.val) self.assertEqual(1, head.next.val) self.assertEqual(2, head.next.next.val) self.assertEqual(3, head.next.next.next.val) self.assertEqual(4, head.next.next.next.next.val) self.assertEqual(4, head.next.next.next.next.next.val) self.assertEqual(5, head.next.next.next.next.next.next.val)
def test_61_rotateRight(self): head = ListNode(1) head.next = ListNode(2) head.next.next = ListNode(3) head.next.next.next = ListNode(4) head = self.solution._61_rotateRight(head, 2) self.assertEqual(3, head.val) self.assertEqual(4, head.next.val) self.assertEqual(1, head.next.next.val) self.assertEqual(2, head.next.next.next.val) self.assertIsNone(head.next.next.next.next)
def swapPairs(self, head: 'ListNode') -> 'ListNode': dummy = ListNode(0) dummy.next = head cur = dummy while cur.next and cur.next.next: # pre = cur.next # post = cur.next.next # cur.next, post.next, pre.next = post, pre, post.next cur.next.next.next, cur.next.next, cur.next = cur.next, cur.next.next.next, cur.next.next cur = cur.next.next # cur.next, cur.next.next.next, cur.next.next = cur.next.next, cur.next, cur.next.next.next # cur = cur.next.next return dummy.next
def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode: dummy = ListNode(None) dummy.next = head f, b = dummy, dummy i = 0 while i < n: f = f.next i += 1 while f.next: f = f.next b = b.next b.next = b.next.next return dummy.next
def removeNthFromEnd(self, head, n): dummy = ListNode(-1) dummy.next = head slow, fast = dummy, dummy for i in range(n): fast = fast.next while fast.next: slow, fast = slow.next, fast.next slow.next = slow.next.next return dummy.next
def test_109_sortedListToBST(self): head = ListNode(-10) head.next = ListNode(-3) head.next.next = ListNode(0) head.next.next.next = ListNode(5) head.next.next.next.next = ListNode(9) root = self.solution._109_sortedListToBST(head) self.assertEqual(0, root.val) self.assertEqual(-10, root.left.val) self.assertEqual(5, root.right.val) self.assertEqual(-3, root.left.right.val) self.assertEqual(9, root.right.right.val)
def deleteDuplicates(self, head: ListNode) -> ListNode: if not head: return head dummy = ListNode(None) dummy.next = head p0, p1 = dummy, dummy.next.next while p1: if p1.val != p0.next.val: p0 = p0.next else: while p1 and p1.val == p0.next.val: p1 = p1.next p0.next = p1 p1 = p1.next if p1 else None return dummy.next
def rotateRight1(self, head, k): """ :type head: ListNode :type k: int :rtype: ListNode """ if not head: return head count = 0 dummy = ListNode(0) dummy.next = head # 无需dummy node cur = dummy while cur.next: count += 1 cur = cur.next k %= count if k == 0: return head cur = dummy for _ in range(count - k): cur = cur.next new_head = cur.next cur.next = None dummy.next = new_head while new_head.next: new_head = new_head.next new_head.next = head # 可以在计算长度时就赋值,减少遍历次数 return dummy.next
def test_86_partition(self): head = ListNode(1) head.next = ListNode(4) head.next.next = ListNode(3) head.next.next.next = ListNode(2) head.next.next.next.next = ListNode(5) head.next.next.next.next.next = ListNode(2) head = self.solution._86_partition(head, 3) self.assertEqual(1, head.val) self.assertEqual(2, head.next.val) self.assertEqual(2, head.next.next.val) self.assertEqual(4, head.next.next.next.val) self.assertEqual(3, head.next.next.next.next.val) self.assertEqual(5, head.next.next.next.next.next.val) self.assertIsNone(head.next.next.next.next.next.next)
def swapPairs(self, head: ListNode) -> ListNode: dummy = ListNode(None) dummy.next = head p = dummy while p.next and p.next.next: # Locate next two nodes. p0 = p.next p1 = p.next.next # Swap p0 and p1. p0.next = p1.next p1.next = p0 p.next = p1 # Proceed p. p = p.next.next return dummy.next
def test_92_reverseBetween(self): head = ListNode(1) head.next = ListNode(2) head.next.next = ListNode(3) head.next.next.next = ListNode(4) head.next.next.next.next = ListNode(5) head.next.next.next.next.next = ListNode(6) head = self.solution._92_reverseBetween(head, 3, 4) self.assertEqual(1, head.val) self.assertEqual(2, head.next.val) self.assertEqual(4, head.next.next.val) self.assertEqual(3, head.next.next.next.val) self.assertEqual(5, head.next.next.next.next.val) self.assertEqual(6, head.next.next.next.next.next.val) self.assertIsNone(head.next.next.next.next.next.next)
def insertionSortList(self, head: ListNode) -> ListNode: dummy = ListNode(0) dummy.next = head p = dummy # p.next is the node to insertion. while p.next: p0 = dummy # p0.next is the position to insert. while p0 != p and p0.next.val < p.next.val: p0 = p0.next node = p.next # Detach the node. p.next = node.next # Insert the node. node.next = p0.next p0.next = node # Advance p if no actual insertion happen. if p0 == p: p = p.next return dummy.next
def swapPairs(self, head): """ :type head: ListNode :rtype: ListNode """ dumy = ListNode(0) dumy.next = head cur = dumy while cur.next and cur.next.next: node1 = cur.next node2 = node1.next nxt = node2.next cur.next = node2 node2.next = node1 node1.next = nxt cur = node1 return dumy.next
def addTwoNumbers(self, l1: 'ListNode', l2: 'ListNode') -> 'ListNode': nums1, nums2 = 0, 0 cur1, cur2 = l1, l2 while cur1: nums1 = nums1 * 10 + cur1.val cur1 = cur1.next while cur2: nums2 = nums2 * 10 + cur2.val cur2 = cur2.next nums1 += nums2 if nums1 == 0: return l1 dummy = ListNode(0) # don't allow to modify the list, so has to create new ListNode while nums1 > 0: nums1, digit = divmod(nums1, 10) cur = ListNode(digit) dummy.next, cur.next = cur, dummy.next return dummy.next
def reverseKGroup(self, head: ListNode, k: int) -> ListNode: if not head or k < 2: return head next_group, i = head, 0 while next_group and i < k: next_group = next_group.next i += 1 if i < k: return head p1, p2 = head, head.next while p2 != next_group: temp = p2.next p2.next = p1 p1 = p2 p2 = temp new_head = p1 head.next = self.reverseKGroup(next_group, k) return new_head
def addTwoNumbers(self, l1: 'ListNode', l2: 'ListNode') -> 'ListNode': dummy1, dummy2 = ListNode(0), ListNode(1) dummy1.next, dummy2.next = l1, l2 carry, cur1, cur2 = 0, dummy1, dummy2 while cur1.next and cur2.next: carry, cur1.next.val = divmod( cur1.next.val + cur2.next.val + carry, 10) cur1, cur2 = cur1.next, cur2.next if not cur1.next: cur1.next = cur2.next while cur1.next and carry == 1: carry, cur1.next.val = divmod(cur1.next.val + carry, 10) cur1 = cur1.next if carry == 1: cur1.next = ListNode(1) return dummy1.next
def removeNthFromEnd(self, head, n): """ :type head: ListNode :type n: int :rtype: ListNode """ root = ListNode(0) root.next = head p1 = p2 = root for i in range(n): p1 = p1.next while p1.next: p1 = p1.next p2 = p2.next # p2.next = p2.next.next if p2.next else None p2.next = p2.next.next # 加了dummy就不需要判断是否为空 return root.next