from utils import print_ll from utils import Node def add_two(l1, l2): curt = dummy = Node(-1) carry = 0 while l1 or l2: v1 = v2 = 0 if l1: v1 = l1.val l1 = l1.next if l2: v2 = l2.val l2 = l2.next val = (v1 + v2 + carry) % 10 carry = (v1 + v2 + carry) // 10 curt.next = Node(val) curt = curt.next if carry: curt.next = Node(carry) return dummy.next if __name__ == '__main__': l1 = build_ll([2, 4, 3]) l2 = build_ll([5, 6, 4]) print_ll(add_two(l1, l2))
Analyze and describe its complexity. ''' from utils import print_ll from utils import build_ll from utils import Node import heapq def merge(head_list): ''' list of heads ''' curt = dummy = Node(-1) heap = [] for head in head_list: heapq.heappush(heap, [head.val, head]) while heap: _, head = heapq.heappop(heap) curt.next = head curt = curt.next if head.next: heapq.heappush(heap, [head.next.val, head.next]) return dummy.next if __name__ == '__main__': lists = [[1, 3, 4, 6], [0, 2, 5, 8], [7, 9]] lists = [build_ll(l) for l in lists] print_ll(merge(lists))
''' Given a sorted linked list, delete all duplicates such that each element appear only once. For example, Given 1->1->2, return 1->2. Given 1->1->2->3->3, return 1->2->3. ''' from utils import build_ll from utils import print_ll def delete_duplicates(head): if not head or not head.next: return head curt = head while curt.next: if curt.val == curt.next.val: curt.next = curt.next.next else: curt = curt.next return head if __name__ == '__main__': head = build_ll([1, 1, 2, 3, 3]) print_ll(delete_duplicates(head))
''' if not head or not head.next: return head slow, fast = head, head.next while fast and fast.next: fast = fast.next.next slow = slow.next return slow if __name__ == '__main__': print('insert') head = utils.build_ll([1, 2, 4, 5]) head = insert(head, 3) utils.print_ll(head) head = insert(head, 0) utils.print_ll(head) head = insert(head, 6) utils.print_ll(head) print('=== ===') print('remove') head = remove(head, 3) utils.print_ll(head) head = remove(head, 0) utils.print_ll(head) head = remove(head, 6) utils.print_ll(head) utils.print_ll(remove(utils.build_ll([3, 3, 3, 2, 4]), 3)) print('=== ===') print('reverse')
Given 1->2->3->4, you should return the list as 2->1->4->3. Your algorithm should use only constant space. You may not modify the values in the list, only nodes itself can be changed. ''' from utils import print_ll from utils import build_ll from utils import Node def rotate(head): prev = dummy = Node(-1) curt = dummy.next = head while curt and curt.next: next = curt.next temp = next.next prev.next = next next.next = curt curt.next = temp prev = curt curt = temp return dummy.next if __name__ == '__main__': head = build_ll([1, 2, 3, 4]) print_ll(rotate(head))
from utils import Node def remove_duplicates_II(head): if not head or not head.next: return head prev = dummy = Node(-1) curt = head is_dup = False while curt.next: if curt.val == curt.next.val: curt.next = curt.next.next is_dup = True else: if is_dup: prev.next = curt.next else: prev.next = curt prev = prev.next curt = curt.next is_dup = False if is_dup: prev.next = None return dummy.next if __name__ == '__main__': head = build_ll([1, 1, 2, 3, 3]) print_ll(remove_duplicates_II(head))
from utils import print_ll from utils import build_ll from utils import Node def rotate(head, k): if not head or not k: return head tail = prev = dummy = Node(-1) dummy.next = head for _ in range(k): if not tail: return head tail = tail.next while tail.next: prev = prev.next tail = tail.next new_head = prev.next prev.next = None tail.next = head return new_head if __name__ == '__main__': head = build_ll([1, 2, 3, 4, 5]) print_ll(rotate(head, 2))
For example, Given 1->4->3->2->5->2 and x = 3, return 1->2->2->4->3->5. ''' from utils import print_ll from utils import build_ll from utils import Node def partition(head, k): less_head = lcur = Node(-1) great_head = gcur = Node(-1) while head: if head.val < k: lcur.next = head lcur = lcur.next else: gcur.next = head gcur = gcur.next head = head.next gcur.next = None lcur.next = great_head.next return less_head.next if __name__ == '__main__': head = build_ll([1, 4, 3, 2, 5, 2]) print_ll(partition(head, 3))
After removing the second node from the end, the linked list becomes 1->2->3->5. Note: Given n will always be valid. Try to do this in one pass. ''' from utils import build_ll from utils import print_ll from utils import Node def remove_nth_from_end(head, n): if not head: return head curt = prev = dummy = Node(-1) dummy.next = head for _ in range(n): curt = curt.next while curt.next: curt = curt.next prev = prev.next prev.next = prev.next.next return dummy.next if __name__ == '__main__': head = build_ll([1, 2, 3, 4, 5]) print_ll(remove_nth_from_end(head, 2))
''' from utils import build_ll from utils import print_ll from utils import Node def merge(l1, l2): curt = dummy = Node(-1) while l1 and l2: if l1.val <= l2.val: curt.next = l1 l1 = l1.next else: curt.next = l2 l2 = l2.next curt = curt.next if l1: curt.next = l1 else: curt.next = l2 return dummy.next if __name__ == '__main__': l1 = build_ll([1, 3, 5]) l2 = build_ll([2, 4, 6]) print_ll(merge(l1, l2))
while curt is not tail: temp = curt.next curt.next = prev.next prev.next = curt curt = temp head.next = tail def reverse_k(head, k): prev = dummy = Node(-1) curt = dummy.next = head while True: tail = curt for _ in range(k): if not tail: return dummy.next tail = tail.next reverse(prev, curt, tail) curt.next = tail prev = curt curt = tail if __name__ == '__main__': head = build_ll([1, 2, 3, 4, 5]) print_ll(reverse_k(head, 2)) head = build_ll([1, 2, 3, 4, 5]) print_ll(reverse_k(head, 3))