Exemplo n.º 1
0
 def merge(h1, h2):
     dummy = tail = ListNode(None)
     while h1 and h2:
         if h1.val < h2.val:
             tail.next, tail, h1 = h1, h1, h1.next
         else:
             tail.next, tail, h2 = h2, h2, h2.next
     tail.next = h1 if h1 else h2
     return dummy.next
Exemplo n.º 2
0
 def recursion(longer, shorter, offset):
     # 如果知道了两个list的长度,找到较长的和较短的,以及两者的差值offset,根据offset判断之后递归的状态
     if not longer:
         return None
     # offset=0,说明两者当前节点长度一样,也就是数位一样,需要相加
     current = ListNode(longer.val if offset else longer.val +
                        shorter.val)
     # post就是当前节点的所有后面的节点的相加结果,因为offset=0,仅说明两者后边的长度相等,但可能还有节点
     # offset不为0,说明longer比shorter还是要长,用longer下一个和shorter继续相加
     post = recursion(longer.next, shorter, offset -
                      1) if offset else recursion(
                          longer.next, shorter.next, 0)
     if post and post.val >= 10:
         # 改变carry,即当前节点的value
         current.val += 1
         post.val -= 10
     current.next = post
     return current
Exemplo n.º 3
0
def remove_nth_node_from_end_of_list(head, n):
    """
    https://leetcode.com/problems/remove-nth-node-from-end-of-list/description/
    删除倒数第N个节点。扫两边,先是找到总长度,然后从头开始数,倒数第N个的时候,把它删除。
    扫一遍:两个指针,快指针先是从head开始走到第n+1各节点,然后同时移动slow和fast,直到fast为None
    此时,slow就是对应的从后往前的第n-1个node,slow.next就是第Nth node,删除掉slow.next即可。
    """
    # 假头来处理特殊情况
    fake_head = ListNode(0)
    fake_head.next = head
    slow = fast = fake_head
    while n >= 0:  # to the n+1 node
        n -= 1
        fast = fast.next
    while fast:
        slow, fast = slow.next, fast.next
    # slow is the n-1 th from end
    slow.next = slow.next.next
    return fake_head.next
Exemplo n.º 4
0
 def plus_one_linked_list_recur(head):
     if not head:
         return ListNode(1)
     carry = AddLinkedList.plus_one_linked_list_recur(head.next)
     if carry != head.next:
         head.val += 1  # carry from next
     if head.val <= 9:  # no carry needed
         return head
     head.val -= 10  # head.val == 10
     carry.next = head
     return carry
Exemplo n.º 5
0
def test(array, count=100, is_simple=True):
    head = ListNode.array_to_nodes(array)
    # possible test cases: 1->2, 1->2->3, 1->2->...->10, 1->2->3->...->100
    print head
    if is_simple:
        linked_list_random = LinkedListRandomNodeSimple(head)
    else:
        linked_list_random = LinkedListRandomNodeReservoir(head)
    wc = {}
    for i in xrange(count):
        val = linked_list_random.get_random()
        wc[val] = wc.get(val, 0) + 1
    print wc
Exemplo n.º 6
0
    def add_two_numbers_original_order_recursion(l1, l2):
        def get_len(head):
            count = 0
            while head:
                count += 1
                head = head.next
            return count

        def recursion(longer, shorter, offset):
            # 如果知道了两个list的长度,找到较长的和较短的,以及两者的差值offset,根据offset判断之后递归的状态
            if not longer:
                return None
            # offset=0,说明两者当前节点长度一样,也就是数位一样,需要相加
            current = ListNode(longer.val if offset else longer.val +
                               shorter.val)
            # post就是当前节点的所有后面的节点的相加结果,因为offset=0,仅说明两者后边的长度相等,但可能还有节点
            # offset不为0,说明longer比shorter还是要长,用longer下一个和shorter继续相加
            post = recursion(longer.next, shorter, offset -
                             1) if offset else recursion(
                                 longer.next, shorter.next, 0)
            if post and post.val >= 10:
                # 改变carry,即当前节点的value
                current.val += 1
                post.val -= 10
            current.next = post
            return current

        len1, len2 = get_len(l1), get_len(l2)
        new_head = ListNode(0)
        longer = l1 if len1 > len2 else l2
        shorter = l2 if len1 > len2 else l1
        new_head.next = recursion(longer, shorter, abs(len1 - len2))
        if new_head.next and new_head.next.val >= 10:
            # 如果new head之后的值大于10,carry=1加到当前new head,此时new head就是结果
            # 否则是new head.next才是最后真正的结果
            new_head.next.val -= 10
            new_head.val += 1
            return new_head
        return new_head.next
Exemplo n.º 7
0
 def add_two_numbers_reverse_order(l1, l2):
     # https://leetcode.com/problems/add-two-numbers/description/
     # test case: a = 1->8->6, b = 1->2->3, result=2->0->0->1
     current = new_head = ListNode(0)
     carry = 0
     while l1 or l2 or carry:
         if l1:
             carry += l1.val
             l1 = l1.next
         if l2:
             carry += l2.val
             l2 = l2.next
         current.val += carry
         carry = 0
         if current.val >= 10:
             current.val -= 10
             carry = 1  # 下次的carry为1
         if l1 or l2 or carry:
             # 如果还有继续的必要,current挪到下一个
             current.next = ListNode(0)
             current = current.next
     return new_head
Exemplo n.º 8
0
 def add_two_numbers_original_order_stack_way(l1, l2):
     # https://leetcode.com/problems/add-two-numbers-ii/description/
     # 如果是原始的顺序,可以用一个stack来逆序遍历;或者将两个输入逆序,相加后再逆序回来
     s1, s2, s3 = list([]), list([]), list([])
     while l1:
         s1.append(l1.val)
         l1 = l1.next
     while l2:
         s2.append(l2.val)
         l2 = l2.next
     c = 0
     while c > 0 or len(s1) > 0 or len(s2) > 0:
         val = c
         val += s1.pop() if len(s1) > 0 else 0
         val += s2.pop() if len(s2) > 0 else 0
         c = 1 if val >= 10 else 0
         val -= 10 if val >= 10 else 0
         s3.append(val)
     temp = head = ListNode(0)  # place holder
     while s3:
         # 逆序遍历stack
         temp.next = ListNode(s3.pop())
         temp = temp.next
     return head.next
Exemplo n.º 9
0
 def plus_one_linked_list_stack(head):
     # https://leetcode.com/problems/plus-one-linked-list/description/
     # head为最大位置的digit,以此类推,用stack,到最后一位时候,+1,如果carry为1,依次pop stack
     if not head:
         return
     stack = list([])
     new_head = ListNode(1)
     new_head.next = node = head
     while node:
         stack.append(node)
         node = node.next
     # 遍历到最后node
     carry = 1
     while stack:
         node = stack.pop()
         node.val += carry
         if node.val >= 10:
             node.val -= 10
         else:
             # 此时carry为0,且stack还有元素,即没有回到最开始的head,不需要用new head
             return head
     return new_head  # 否则返回new head,初始化为1
Exemplo n.º 10
0
def merge_k_sorted_linked_list(list_heads):
    """
    https://leetcode.com/problems/merge-k-sorted-lists/description/
    用优先队列,初始化为每个head节点进入队列,长度<=K,max heap,因为要找最小值
    然后每次从里面找到最小的head,更新方式为,找到head的下一个node加入到队列中去(如果有的话)
    follow up可能是,merge K sorted arrays,类似的想法,heap里面需要存放对应的哪个array,以及该array的遍历index
    """
    new_head = result_node = ListNode(0)
    heap = [(n.val, n) for n in list_heads if n]  # n.val就是heap的priority
    # 初始化max heap
    heapify(heap)
    while heap:
        curr_node = heap[0][1]
        if curr_node.next:
            # heap replace: Pop and return the current smallest value, and add the new
            heapreplace(heap, (curr_node.next.val, curr_node.next))
        else:
            # 此时heap size-1,因为curr node没有后继节点了
            heappop(heap)
        # 更新结果
        result_node.next = curr_node
        result_node = result_node.next
    return new_head.next
Exemplo n.º 11
0
        while p2:
            p3 = p2.next
            p2.next = p1
            p1, p2 = p2, p3
        return p1
    if not head or not head.next:
        return head
    # first find k nodes, then reverse them, assuming more than one node
    p, i = head, 1
    while p.next and i < k:
        p, i = p.next, i + 1
    if i == k:
        # find k nodes
        afterKHead, p.next = p.next, None
        newHead = reverse(head)
        # original head is now the tail of new head
        head.next = reverseNodesKGroup(afterKHead, k)
        return newHead
        # less than k nodes
    return head


from utility.entity import ListNode
for k in [2, 3, 5]:
    head = ListNode.array_to_nodes([1,2,3,4,5,6,7])
    print k, reverseNodesKGroup(head, k)

for k in [3]:
    head = ListNode.array_to_nodes([1,2,3,4,5])
    print k, reverseNodesKGroup(head, k)