def partition(self, head, x): """ :type head: ListNode :type x: int :rtype: ListNode """ if head is None: return None dummy_before = ListNode(0) cur_before = dummy_before dummy_after = ListNode(0) cur_after = dummy_after cur_head = head while cur_head is not None: if cur_head.val < x: cur_before.next = cur_head cur_before = cur_before.next else: cur_after.next = cur_head cur_after = cur_after.next cur_head = cur_head.next cur_before.next = dummy_after.next cur_after.next = None return dummy_before.next
def test_it_returns_the_correct_node(self): l = ListNode('1') last = last_of_list(l) self.assertEqual(last.value, '1') l = shift_list(ListNode('0'), l) last = last_of_list(l) self.assertEqual(last.value, '1')
def sortList(self, head: ListNode) -> ListNode: if (head is None) or (head.next is None): return head # get length of linked list n = 0 curr = head while curr: n += 1 curr = curr.next header = ListNode() # dummy header node header.next = head step = 1 while step < n: curr = header.next tail = header while curr: left = curr right = split(left, step) curr = split(right, step) tail = merge(left, right, tail) #step *= 2 step <<= 1 return header.next
def reverseKGroup(self, head, k): """ :type head: ListNode :type k: int :rtype: ListNode """ dumy = ListNode(0) dumy.next = head cur = dumy while cur is not None and cur.next is not None: sub_head = cur.next sub_tail = cur.next sub_len = 1 for i in range(0, k - 1): sub_tail = sub_tail.next if sub_tail is None: break sub_len += 1 if sub_len == k: next_head = sub_tail.next new_head = self.revser_list(sub_head, k) sub_head.next = next_head cur.next = new_head cur = sub_head else: break return dumy.next
def sum_list(l1: Optional[ListNode[int]], l2: Optional[ListNode[int]]) -> Optional[ListNode[int]]: n1, n2, carry = l1, l2, 0 head, runner = None, None while n1 or n2 or carry: v1 = n1.val if n1 else 0 v2 = n2.val if n2 else 0 total = v1 + v2 + carry carry = total // 10 num = total % 10 if n1: n1 = n1.next if n2: n2 = n2.next if not head: head = ListNode(num) runner = head else: runner.next = ListNode(num) runner = runner.next return head
def swap_nodes_in_pairs(head: ListNode) -> ListNode: # Create a dummy node pointing to head. dummy = ListNode(0) dummy.next = head current = dummy # Iterate through the list, starting from the dummy node # each time exchange the order of the two nodes after current. # Stop when there is only 0 or 1 node left. while current.next and current.next.next: # To avoid confusion, we can rename the two nodes to be # exchanged as node1 and node2. node1 = current.next node2 = current.next.next # Exchange node1 and node2: # current.next pointing to node2 current.next = node2 # node1.next pointing to node2.next node1.next = node2.next # node2.next pointing to node 1 node2.next = node1 # Move current to node1, we will exchange the two nodes # after node1 in the next iteration. current = node1 return dummy.next
def pad_zero(l: ListNode[int], n: int): head = l for _ in range(n): node = ListNode(0) node.next = head head = node return head
def partition(ll: LinkedList[T], x: T) -> LinkedList[T]: before_head, before_tail, after_head, after_tail = None, None, None, None # runner n = ll.head while n: if n.val < x and before_head == None: before_head = ListNode(n.val) before_tail = before_head elif n.val < x and before_head != None: before_tail.next = ListNode(n.val) before_tail = before_tail.next if n.val >= x and after_head == None: after_head = ListNode(n.val) after_tail = after_head elif n.val >= x and after_head != None: after_tail.next = ListNode(n.val) after_tail = after_tail.next n = n.next if not before_tail: return LinkedList(after_head) if before_tail: before_tail.next = after_head return LinkedList(before_head)
def insert(self, head: ListNode, x: int) -> ListNode: if not head: # case 0: empty list head = ListNode(x) head.next = head return head pre = head cur = head.next while 1: if pre.val <= x <= cur.val: # case 1: insert in middle break if pre.val > cur.val: # case 2: pre is tail (max), cur is head (min) if x > pre.val or x < cur.val: break pre = cur cur = cur.next if pre == head: # case 3: we've looped around once; all elts equal break pre.next = ListNode(x, cur) return head
def addTwoNumbers(self, l1, l2): """ :type l1: ListNode :type l2: ListNode :rtype: ListNode """ dummy = ListNode(0) p = dummy add_on = 0 while l1 is not None or l2 is not None: x = 0 if l1 is None else l1.val y = 0 if l2 is None else l2.val next_digit = x + y + add_on if next_digit < 10: p.next = ListNode(next_digit) add_on = 0 else: p.next = ListNode(next_digit % 10) add_on = 1 l1 = l1.next if l1 is not None else None l2 = l2.next if l2 is not None else None p = p.next if add_on > 0: p.next = ListNode(1) return dummy.next
def pad_list(head, n): """Pad a linked list with zeros before head""" for i in range(n): new_head = ListNode(0) new_head.next = head head = new_head return head
def add_lists(l1, l2): """ Two lists contain digits stored in reverse order """ p = res = None carry = 0 while l1 is not None or l2 is not None: data1 = 0 data2 = 0 if l1 is not None: data1 = l1.data l1 = l1.next if l2 is not None: data2 = l2.data l2 = l2.next data = (data1 + data2 + carry) % 10 carry = 1 if data1 + data2 + carry >= 10 else 0 if res is None: res = create_list([data]) p = res else: p.next = ListNode(data) p = p.next if carry > 0: p.next = ListNode(1) return res
def partition_list(head: ListNode, x: int) -> ListNode: """ Break Down and Concatenate We can break down the list into two parts: 1. Nodes have value smaller than x; 2. Nodes have value larger than or equal to x. Time Complexity - O(N) - Iterate through the list once. Space Complexty - O(1) - For pointers. """ # Use two dummy nodes to store two break-down lists. s = smaller = ListNode(-1) l = larger = ListNode(-1) while head: if head.val < x: s.next = head s = s.next else: l.next = head l = l.next head = head.next # Last node of larger is the end. l.next = None # Concatenate two lists, as smaller will be followed by larger. s.next = larger.next return smaller.next
def merge(l1: ListNode, l2: ListNode) -> ListNode: """ Merge two lists one element by one. """ while l1 and l2: l1_temp = l1.next l2_temp = l2.next l1.next = l2 l1 = l1_temp l2.next = l1 l2 = l2_temp
def merge_two_sorted_lists(l1: ListNode, l2: ListNode) -> ListNode: """ Merge two sorted lists. """ if not l1: return l2 if not l2: return l1 if l1.val <= l2.val: l1.next = merge_two_sorted_lists(l1.next, l2) return l1 else: l2.next = merge_two_sorted_lists(l1, l2.next) return l2
def removeNthFromEnd(self, head, n): dummy = ListNode(0) dummy.next = head slow = dummy fast = dummy for i in range(n): fast = fast.next while fast.next != None: slow = slow.next fast = fast.next slow.next = slow.next.next return dummy.next
def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode: if l1 is None: return l2 if l2 is None: return l1 if l1.val <= l2.val: l1.next = self.mergeTwoLists(l1.next, l2) return l1 l2.next = self.mergeTwoLists(l1, l2.next) return l2
def partial_sum(ln1: Optional[ListNode[int]], ln2: Optional[ListNode[int]]): # the length of ln1 and ln2 is equal now n1, n2, carry, next_sum_node = ln1, ln2, 0, None if n1.next and n2.next: next_sum_node, carry = partial_sum(n1.next, n2.next) total = carry + n1.val + n2.val carry = total // 10 sum = total % 10 sum_node = ListNode(sum) sum_node.next = next_sum_node return sum_node, carry
def mergeTwoLists2(self, l1: ListNode, l2: ListNode) -> ListNode: """ Solution #2: recursively Time: O(n) Space: O(1) """ if not l1: return l2 if not l2: return l1 if l1.val < l2.val: l1.next = self.mergeTwoLists2(l1.next, l2) return l1 else: l2.next = self.mergeTwoLists2(l1, l2.next) return l2
def removeElements(self, head: ListNode, val: int) -> ListNode: header = ListNode() # dummy header node header.next = head pre = header # last node that doesn't have target value while head: if head.val == val: pre.next = head.next else: pre = head # pre.next head = head.next return header.next
def add_lists2(l1, l2): len1 = get_length(l1) len2 = get_length(l2) if len1 < len2: l1 = pad_list(l1, len2 - len1) else: l2 = pad_list(l2, len1 - len2) t = [] carry = add_lists2_aux(l1, l2, t) res = create_list(t) if carry > 0: new_head = ListNode(1) new_head.next = res res = new_head return res
def insertionSortList(self, head: ListNode) -> ListNode: if not head: return head header = ListNode() # dummy header node for new linked list curr = head # the node from original list to be inserted pre = header while curr: # save so we can update curr at end of loop next = curr.next # find where to insert if (not pre.next) or (pre.next.val >= curr.val): pre = header while pre.next and pre.next.val < curr.val: pre = pre.next # insert between pre and pre.next curr.next = pre.next pre.next = curr # update curr using saved "next" curr = next return header.next
def reverse_linked_list_recursion(head: ListNode) -> ListNode: """ Reverse with recursion We can assume the following nodes (after head) have been reversed and we only need to reverse the current node and current.next. It'll be hard for human beings to understand the full process of recursion, as our brains are not designed to push many items in stack, so we need to focus on one stage (see reverse_linked_list_single_case.jpg for reference), rather than try to understand the full process. For a single stage: Given an input node head, reverse the linked list starting with head, and return the reversed new head. Time Complexity - O(N) - Iterate the list once. Space Complexity - O(N) - For recursion stack. """ # Recursion stop condition. if head == None or head.next == None: return head # Reverse the following nodes. # temp will be the last node or the head node for the reversed list. temp = reverse_linked_list_recursion(head.next) # Reverse - the next node after head shall point to head now. head.next.next = head # Pointing head to None to avoid dead loop. head.next = None # Always return the new head node. return temp
def merge_k_sorted_lists_heapq(input_lists: list) -> ListNode: """ Solution - Min Heap We first insert the first element (also smallest as the lists are sorted) of each linked list in a min heap. After this, we can take out the smallest element from the heap and add it to the merged list. After removing the smallest element from the heap, we can insert the next element of the same list into the heap. Repeat previous steps to populate the merged list in sorted order. Time Complexity - O(kn*logk) - the number of elements in the priority queue will be less than k, so the time complexity for insertion and deletion will be O(logk), there are at most k*n elements (every node is inserted and deleted once), so the total time complexity will be O(kn*logk) Space Complexity - O(k) - for the priority queue (min-heap). """ dummy = ListNode(-1) current = dummy min_heap = [] # Put the root of each list in the min heap for root in input_lists: if root: heapq.heappush(min_heap, root) # Pop the smallest element from the min heap and add it to the result sorted list. while min_heap: node = heapq.heappop(min_heap) current.next = node current = current.next # If the element poped still have next node, then add it into the heap. if node.next: heapq.heappush(min_heap, node.next) return dummy.next
def add(a, b): result = ListNode(0) result_head = result carry = 0 while a or b or carry: a_digit = a.value if a else 0 b_digit = b.value if b else 0 a = a.next_node if a else None b = b.next_node if b else None digit_sum = a_digit + b_digit + carry new_digit = digit_sum % 10 carry = digit_sum / 10 result.next_node = ListNode(new_digit) result = result.next_node return result_head.next_node
def delete_duplicates_three_pointers(head: ListNode) -> ListNode: """ Three pointers The solution is similar to the two pointers one. The difference is in this method, we are using `b` pointing to head.next rather than head. So to compare whether two nodes have same values, we need to use: a.next.val == b.val. When the two pointers are pointing to different values, both a and b move forward one step, while when they pointing to same values, there are some differentce. 1. a.next pointing to b now; 2. Pointer b has to handle bound problems, where b could be None, so we can't use b = b.next directly, instead we have to see if b is already Nonem, so we won't get an None has no next property error. Here `a` is called `preserve` and `b` is called `current`. Time Complexity - O(N) - Iterate the linked list once. Space Complexity - O(1) - Constant space for pointers. """ # Edge cases, empty list or single element list. if not (head and head.next): return head # Create dummy node pointing to head dummy = ListNode(-1) dummy.next = head preserve = dummy current = head.next # Current could be None, such as 1 -> 1. while current: # If the nodes have different values, move forward one step. if preserve.next.val != current.val: preserve = preserve.next current = current.next else: # If the nodes have same values, then move current node until preseve and current # pointing to different values. while current and preserve.next.val == current.val: current = current.next # Different from two pointers solution, here a.next pointing to b. preserve.next = current # Current could pointing to None after the while loop before. current = current.next if current else None return dummy.next
def delete_duplicates(head: ListNode) -> ListNode: """ Two pointers To handle cases where the first node is also a duplicated node, we can use dummy node to handle this. Firstly, we define two pointers `a` and `b`, where `a` pointing to the dummy node, and `b` pointing to the head node. If the node `a` pointing to has a different value comparing to the node `b` is pointing to, then both `a` and `b` move forward for one step. If the values are the same, then only move `b`, and `b` keeps moving until the values are different. Here we are comparing a.next.val == b.next.val. While the values that the two pointers are pointing to are equal, we can use a while loop to keep `b` moving until we've filtered duplicated nodes. Here `a` is called `preserve` and `b` is called `current`. Time Complexity - O(N) - Iterate the linked list once. Space Complexity - O(1) - Constant space for pointers. """ # Edge cases, empty list or single element list. if not (head and head.next): return head # Create dummy node pointing to head. dummy = ListNode(0) dummy.next = head preserve = dummy current = head while current and current.next: # If the nodes have different values, move forward one step. if preserve.next.val != current.next.val: preserve = preserve.next current = current.next else: # If the nodes have same values, then move current node until preseve and current # pointing to different values. Exclude all those nodes have same values. while current and current.next and preserve.next.val == current.next.val: current = current.next preserve.next = current.next current = current.next return dummy.next
def addTwoNumbers(self, l1, l2): """ :type l1: ListNode :type l2: ListNode :rtype: ListNode """ head = ListNode(0) l = head rem = 0 prevRem = 0 while l1 is not None: val = (l1.val + l2.val) % 10 l.next = ListNode(val + prevRem) prevRem = int(((l1.val + l2.val) - val) / 10) l = l.next l1 = l1.next l2 = l2.next return head.next
def addTwoNumbers(l1, l2): dummy_node = ListNode(0) p1 = l1 p2 = l2 carry = 0 curr = dummy_node while p1 != None or p2 != None: x = p1.val if p1 != None else 0 y = p2.val if p2 != None else 0 sum = carry + x + y carry = sum//10 curr.next = ListNode(sum%10) curr = curr.next if p1 != None: p1 = p1.next if p2 != None: p2 = p2.next if carry > 0: curr.next = ListNode(carry) return dummy_node.next
def swap_pairs(head): """ :type head: ListNode :rtype: ListNode """ node = ListNode(-1) node.next = head pre = node while pre.next and pre.next.next: l1 = pre.next l2 = pre.next.next nxt = l2.next l1.next = nxt l2.next = l1 pre.next = l2 pre = l1 return node.next
def addTwoNumbers(self, A, B): r = ListNode(0) head = r rem = 0 while A is not None or B is not None: a = 0 if A: a = A.val b = 0 if B: b = B.val v = a + b + rem rem = 0 if v > 9: rem = 1 v = int(str(v)[1]) r.next = ListNode(v) r = r.next if A: A = A.next if B: B = B.next if rem: r.next = ListNode(rem) r = head.next cnt = 0 n = 0 while r is not None: if r.val == 0: cnt += 1 else: cnt = 0 n += 1 r = r.next # print n, cnt r = head.next if cnt: for i in range(n - cnt - 1): r = r.next r.next = None # print l2a(head.next) return head.next
if tmp >= 10: carryover = tmp / 10 tmp = tmp % 10 else: carryover = 0 lcount.val = tmp ltmp = lcount lcount = lcount.next if carryover > 0: ltmp.next = ListNode(carryover) return lhead l1 = ListNode(2) l1.next = ListNode(4) l1.next.next = ListNode(3) #print l1 l2 = ListNode(5) l2.next = ListNode(6) l2.next.next = ListNode(4) #print l2 sol = Solution() print sol.addTwoNumbers(l1,l2) l3 = ListNode(1) l4 = ListNode(9) l4.next = ListNode(9)