def reverse_k_group(head, k): stack = deque() fake_head = ListNode(None) fake_head.next = head group_head = fake_head while True: has_group = True runner = group_head.next for i in xrange(k): if not runner: has_group = False break stack.append(runner) runner = runner.next if not has_group: return fake_head.next group_tail = runner next_head = group_head.next while stack: node = stack.pop() group_head.next = node group_head = group_head.next group_head.next = group_tail group_head = next_head return fake_head.next
def _test(self, head, n, expected): head = ListNode.from_array(head) actual = Solution().removeNthFromEnd(head, n) actual = ListNode.to_array(actual) self.assertEqual(expected, actual)
def _test(self, root, k, expected): root = ListNode.from_array(root) actual = Solution().splitListToParts(root, k) actual = [ListNode.to_array(node) for node in actual] self.assertEqual(expected, actual)
def _test(self, head, k, expected): head = ListNode.from_array(head) actual = Solution().reverseKGroup(head, k) actual = ListNode.to_array(actual) self.assertEqual(expected, actual)
def partition(self, head: ListNode, x: int) -> ListNode: if not head: return head pre = ListNode() pre.next = head cur = head prefirst = pre head = pre firstGreater: ListNode = None while cur: if not firstGreater and cur.val >= x: firstGreater = cur if firstGreater and cur.val < x: prefirst.next = cur pre.next = cur.next cur.next = firstGreater prefirst = cur cur = pre.next continue pre = pre.next cur = cur.next if not firstGreater: prefirst = prefirst.next return head.next
def addTwoNumbers(self, l1, l2): """ :type l1: ListNode :type l2: ListNode :rtype: ListNode """ r = 0 prev = None head = None p, q = l1, l2 while (p is not None or q is not None): i = p.val if p else 0 j = q.val if q else 0 x = i + j + r r = x / 10 x = x % 10 n = ListNode(x) prev = n if p: p = p.next if q: q = q.next # Edge case, when 2 last number sum > 10 if r != 0: n = ListNode(r) if prev: prev.next = n return head
def _test(self, head, expected): head = ListNode.from_array(head) actual = Solution().sortList(head) actual = ListNode.to_array(actual) self.assertEqual(expected, actual)
def oddEvenList(self, head): """ :type head: ListNode :rtype: ListNode """ odd_head = ListNode(0) odd = odd_head even_head = ListNode(0) even = even_head while True: if not head: break odd.next = head odd = head head = head.next if not head: break even.next = head even = head head = head.next odd.next = even_head.next even.next = None return odd_head.next
def _test(self, head, x, expected): head = ListNode.from_array(head) actual = Solution().removeElements(head, x) actual = ListNode.to_array(actual) self.assertEqual(expected, actual)
def _test(self, l1, l2, expected): l1 = ListNode.from_array(l1) l2 = ListNode.from_array(l2) actual = Solution().addTwoNumbers(l1, l2) actual = ListNode.to_array(actual) self.assertEqual(expected, actual)
def _test(self, node, expected): node = ListNode.from_array(node) Solution().deleteNode(node) actual = ListNode.to_array(node) self.assertEqual(expected, actual)
def removeElements2(self, head: ListNode, val: int) -> ListNode: firstNode = ListNode(0) firstNode.next = head pre, cur = firstNode, head while cur: if cur.val == val: pre.next = cur.next else: pre = cur cur = cur.next return firstNode.next
def swap_pairs(head): fake_head = ListNode(None) fake_head.next = head prev = fake_head while prev.next and prev.next.next: r1 = prev.next r2 = r1.next r1.next = r2.next prev.next = r2 r2.next = r1 prev = r return fake_head.next
def _test(self, a, b_before_intersection, a_len_before_intersection): a = ListNode.from_array(a) b = ListNode.from_array(b_before_intersection) intersection = a for _ in range(a_len_before_intersection): intersection = intersection.next b_end = b while b_end.next: b_end = b_end.next b_end.next = intersection actual = Solution().getIntersectionNode(a, b) self.assertEqual(intersection, actual)
def _sort(lo): if not lo.next: return lo mid = lo tail = lo while tail and tail.next and tail.next.next: mid = mid.next tail = tail.next.next hi = mid.next mid.next = None lo = _sort(lo) hi = _sort(hi) dummy = ListNode(0) prev = dummy while lo and hi: if lo.val <= hi.val: prev.next = lo prev = lo lo = lo.next else: prev.next = hi prev = hi hi = hi.next if lo: prev.next = lo else: prev.next = hi return dummy.next
def mergeTwoLists(self, l1, l2): """ :type l1: ListNode :type l2: ListNode :rtype: ListNode """ if l1 is None: return l2 if l2 is None: return l1 # It's hard to merge l1 into l2 or l2 into l1 # The merging may be alternating # It's easier to form a new list dummyHead = ListNode(-1) runner = dummyHead while l1 and l2: if l1.val <= l2.val: runner.next = l1 l1 = l1.next runner = runner.next else: runner.next = l2 l2 = l2.next runner = runner.next if l1 is not None: runner.next = l1 if l2 is not None: runner.next = l2 return dummyHead.next
def partition(self, head: Optional[ListNode], x: int) -> Optional[ListNode]: dummy_lo = lo = ListNode(0) dummy_hi = hi = ListNode(0) while head: if head.val < x: lo.next = head lo = head else: hi.next = head hi = head head = head.next lo.next = dummy_hi.next hi.next = None return dummy_lo.next
def swapPairs(self, head): """ :type head: ListNode :rtype: ListNode """ dummy = ListNode(0) dummy.next = head curr = dummy while curr.next and curr.next.next: a, b, c = curr.next, curr.next.next, curr.next.next.next curr.next = b b.next = a a.next = c curr = a return dummy.next
def removeElements(self, head: ListNode, val: int) -> ListNode: if not head: return None nxt = self.removeElements(head.next, val) if head.val == val: return nxt head.next = nxt return head
def test(self): cases = utils.load_test_json(__file__).test_cases for case in cases: args = str(case.args) head = ListNode.from_array(case.args.head) actual = Solution().oddEvenList(head) actual = ListNode.to_array(actual) self.assertEqual(case.expected, actual, msg=args)
def addTwoNumbers(self, l1, l2): """ :type l1: ListNode :type l2: ListNode :rtype: ListNode """ l1 = reverse_list(l1) l2 = reverse_list(l2) carry = 0 sum_root = ListNode(0) sum_ = sum_root while l1 and l2: digit = l1.val + l2.val + carry if digit >= 10: digit -= 10 carry = 1 else: carry = 0 node = ListNode(digit) sum_.next = node sum_ = node l1 = l1.next l2 = l2.next if l2: l1 = l2 while l1: digit = l1.val + carry if digit >= 10: digit -= 10 carry = 1 else: carry = 0 node = ListNode(digit) sum_.next = node sum_ = node l1 = l1.next if carry: sum_.next = ListNode(carry) return reverse_list(sum_root.next)
def sortList(self, head): """ :type head: ListNode :rtype: ListNode """ n = count(head) parent = ListNode(0) parent.next = head sublen = 1 while True: new_sublen = sublen << 1 prev = parent hi_node = prev.next for lo in range(0, n, new_sublen): lo_end = min(lo + sublen, n) hi = lo_end hi_end = min(hi + sublen, n) lo_node = hi_node for _ in range(hi - lo): hi_node = hi_node.next for _ in range(hi_end - lo): if hi >= hi_end or lo < lo_end and lo_node.val <= hi_node.val: prev.next = lo_node prev = lo_node lo_node = lo_node.next lo += 1 else: prev.next = hi_node prev = hi_node hi_node = hi_node.next hi += 1 if new_sublen >= n: break sublen = new_sublen prev.next = None return parent.next
def addTwoNumbers(self, l1, l2): """ :type l1: ListNode :type l2: ListNode :rtype: ListNode """ dummy = ListNode(0) cur = dummy carry = 0 # don't forget initialization while l1 or l2 or carry: if l1: carry += l1.val l1 = l1.next if l2: carry += l2.val l2 = l2.next cur.next = ListNode(carry % 10) cur = cur.next carry //= 10 return dummy.next
def mergeKLists(lists): s = [x for x in lists if x is not None] s = build_heap(s) dummy = ListNode(None) tmp = dummy while len(s) > 0: n = s[0] if n is not None: node = ListNode(n.val) tmp.next = node tmp = node if n.next is None: s = pop_heap(s) else: s[0] = n.next heapify(s, 0) head = dummy.next return head
def removeNthFromEnd(self, head, n): """ :type head: ListNode :type n: int :rtype: ListNode """ dummy = ListNode(0) dummy.next = head lo = dummy for _ in range(n): head = head.next while head: head = head.next lo = lo.next lo.next = lo.next.next return dummy.next
def _test(self, nums): head = ListNode.from_array(nums) solution = Solution(head) iteration = 1000 hit = 0 for _ in range(iteration): val = solution.getRandom() if val == nums[0]: hit += 1 self.assertAlmostEqual(1.0 / len(nums), float(hit) / iteration, places=1)
def process_args(args): args.head = ListNode.from_array(args.head) if args.pos >= 0: cycle_start = args.head for i in range(args.pos): cycle_start = cycle_start.next curr = cycle_start while curr.next: curr = curr.next curr.next = cycle_start del args.pos
def deleteDuplicates(self, head): """ :type head: ListNode :rtype: ListNode """ if not head: return None parent = ListNode(head.val - 1) parent.next = head head = parent while head.next and head.next.next: val = head.next.val if head.next.next.val == val: next_ = head.next.next.next while next_ and next_.val == val: next_ = next_.next head.next = next_ else: head = head.next return parent.next
def reverseKGroup(head, k): """ :type head: ListNode :type k: int :rtype: ListNode """ dummy = ListNode(0) dummy.next = head p = dummy i = 1 node = head while node: next_node = node.next print(i, node.data) if i == k: new_head, tail_node = reverse(head, k) p.next = new_head p = tail_node tail_node.next = next_node head = next_node i = 0 node = next_node i = i + 1 return dummy.next
def deleteDuplicates(self, head: ListNode) -> ListNode: if not head or not head.next: return head node = ListNode(0) node.next = head pre, cur, nxt = node, head, head.next while nxt: rep = False while nxt and cur.val == nxt.val: rep = True nxt = nxt.next if rep: pre.next = nxt if not nxt: break else: cur = nxt nxt = nxt.next else: pre = pre.next cur = cur.next nxt = nxt.next return node.next