Beispiel #1
0
    def removeZeroSumSublists(self, head: ListNode) -> ListNode:
        """
        TODO 前缀和 掌握 ; so Amazing
        我们可以考虑如果给的入参不是链表是数组的话,只需要求出前缀和,对于前缀和相同的项,
        那他们中间的部分即是可以消除掉的,比如以 [1, 2, 3, -3, 4] 为例,其前缀和数组为 [1, 3, 6, 3, 7] ,
        我们发现有两项均为 3,则 6 和 第二个 3 所对应的原数组中的数字是可以消掉的。
        换成链表其实也是一样的思路,把第一个 3 的 next 指向第二个 3 的 next 即可

        """
        seen = dict()
        dummy = ListNode(0)
        dummy.next = head
        # // 首次遍历建立 节点处链表和<->节点 哈希表
        # // 若同一和出现多次会覆盖,即记录该sum出现的最后一次节点
        prefix = 0
        cur = dummy
        while cur:
            prefix += cur.val
            seen[prefix] = cur
            cur = cur.next
        cur2 = dummy
        prefix = 0
        # // 第二遍遍历 若当前节点处sum在下一处出现了则表明两结点之间所有节点和为0 直接删除区间所有节点

        while cur2:
            prefix += cur2.val
            cur2.next = seen[prefix].next
            cur2 = cur2.next
        return dummy.next
    def partition(self, head: ListNode, x: int) -> ListNode:
        """
        86
        :param head:
        :param x:
        :return:
        """
        if not head:
            return head
        less_head = less_node = None
        equal_more_than_head = equal_more_than_node = None
        node = head
        while node:
            val = node.val
            if val < x:
                if less_head is None:
                    less_head = less_node = ListNode(val)
                else:
                    less_node.next = ListNode(val)
                    less_node = less_node.next
            else:
                if equal_more_than_head is None:
                    equal_more_than_head = equal_more_than_node = ListNode(val)
                else:
                    equal_more_than_node.next = ListNode(val)
                    equal_more_than_node = equal_more_than_node.next
            node = node.next

        if less_head is None:
            new_head = equal_more_than_head
        else:
            less_node.next = equal_more_than_head
            new_head = less_head
        return new_head
Beispiel #3
0
    def removeZeroSumSublists(self, head: ListNode) -> ListNode:
        """

        """
        vals = []
        cur = head
        while cur:
            if cur.val != 0:
                vals.append(cur.val)
            cur = cur.next
        i = 0
        while 0 <= i < len(vals):
            sum = vals[i]
            j = i + 1
            while j < len(vals):
                sum += vals[j]
                if sum == 0:
                    vals[i:j + 1] = []
                    i = i - 1
                    break
                j += 1
            i += 1
        dummy = ListNode(-1)
        pos = dummy
        for v in vals:
            pos.next = ListNode(v)
            pos = pos.next
        return dummy.next
Beispiel #4
0
def test_solutions():
    inter = ListNode.initList([1, 8, 4, 5])
    headA = ListNode.initList([4])
    headB = ListNode.initList([5, 0])
    headA.next = inter
    headB.next = inter
    res = Solution().getIntersectionNode(headA, headB)
    assert res == inter
Beispiel #5
0
def test_solutions():
    l1 = ListNode.initList([4, 1, 8, 4, 5])
    l2 = ListNode.initList([5, 0])
    l2.next.next = l1.next
    res = Solution().getIntersectionNode(l1, l2)
    res1 = Solution1().getIntersectionNode(l1, l2)
    assert res == l1.next
    assert res1 == l1.next
Beispiel #6
0
 def deleteNode(self, head: ListNode, val: int) -> ListNode:
     dummy = ListNode(-1)
     dummy.next = head
     prev, cur = dummy, head
     while cur:
         if cur.val == val:
             break
         prev, cur = cur, cur.next
     prev.next = cur.next
     return dummy.next
Beispiel #7
0
def test_solution():
    cycle = ListNode.initList([2, 0, -4])
    cur = cycle
    while cur.next:
        cur = cur.next
    cur.next = cycle
    head = ListNode(3)
    head.next = cycle
    res = Solution().detectCycle(head)
    assert res and res.val == 2
Beispiel #8
0
 def test_swapPairs(self):
     node1 = ListNode(1)
     node2 = ListNode(2)
     node1.next = node2
     node3 = ListNode(3)
     node2.next = node3
     node4 = ListNode(4)
     node3.next = node4
     print_linked_list(node1)
     # node = self.sln.swapPairs(node1)
     node = self.sln.swapPairs(node2)
     print_linked_list(node)
    def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
        dummy = ListNode(-1)
        dummy.next = head
        first = head
        second = dummy
        for i in range(n):
            first = first.next
        while first:
            first = first.next
            second = second.next

        second.next = second.next.next
        return dummy.next
 def deleteNodes(self, head: ListNode, m: int, n: int) -> ListNode:
     dummy = ListNode(-1)
     dummy.next = head
     cur = dummy
     while cur.next:
         p, q = m, n
         while p and cur.next:
             cur = cur.next
             p -= 1
         while q and cur.next:
             cur.next = cur.next.next
             q -= 1
     return dummy.next
 def addAtIndex(self, index: int, val: int) -> None:
     """
     Add a node of value val before the index-th node in the linked list. If index equals to the length of linked list, the node will be appended to the end of linked list. If index is greater than the length, the node will not be inserted.
     """
     if not 0 <= index <= self.__size:
         return
     pre = self.__dummy_head
     node = ListNode(val)
     for _ in range(index):
         pre = pre.next
     node.next = pre.next
     pre.next = node
     self.__size += 1
Beispiel #12
0
    def deleteDuplicates(self, head: ListNode) -> ListNode:
        dummy = ListNode(-1)
        dummy.next = head

        cur = dummy
        while cur.next and cur.next.next:
            if cur.next.val == cur.next.next.val:
                x = cur.next.val
                while cur.next and cur.next.val == x:
                    cur.next = cur.next.next
            else:
                cur = cur.next

        return dummy.next
Beispiel #13
0
 def mergeKLists(self, lists: List[ListNode]) -> ListNode:
     """Me  O(NlogN) """
     min_heap = []
     heapq.heapify(min_heap)
     for head in lists:
         while head:
             heapq.heappush(min_heap, head.val)
             head = head.next
     dummyHead = ListNode(-1)
     cur_head = dummyHead
     while min_heap:
         val = heapq.heappop(min_heap)
         cur_head.next = ListNode(val)
         cur_head = cur_head.next
     return dummyHead.next
 def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
     dummy_head = ListNode(None)
     dummy_head.next = head
     first = dummy_head
     second = dummy_head
     for i in range(1, n + 1):
         first = first.next
     while first.next:
         first = first.next
         second = second.next
     if second.next:
         second.next = second.next.next
     else:
         second.next = None
     return dummy_head.next
 def deleteNodes(self, head: ListNode, m: int, n: int) -> ListNode:
     dummy = ListNode(-1)
     dummy.next = head
     cur = head
     pre = None
     while cur:
         p, q = m, n
         while p and cur:
             pre = cur
             cur = cur.next
             p -= 1
         while q and cur:
             cur = cur.next
             q -= 1
         pre.next = cur
     return dummy.next
    def reorderList(self, head: ListNode) -> None:
        """
        Do not return anything, modify head in-place instead.
        TODO
        """
        if not (head and head.next):
            return
        fast, slow, prev = head, head, None
        while fast and fast.next:
            fast, slow, prev = fast.next.next, slow.next, slow
        current, prev.next, prev = slow, None, None

        while current:
            current.next, prev, current = prev, current, current.next
        l1, l2 = head, prev

        dummy = ListNode(-1)
        current = dummy
        while l1 and l2:
            current.next = l1
            current = l1
            l1 = l1.next
            # print(dummy,current, l1, l2, sep="\t")

            current.next, current, l2 = l2, l2, l2.next
Beispiel #17
0
 def reverseList(self, head: ListNode) -> ListNode:
     if not (head and head.next):
         return head
     p = self.reverseList(head.next)
     head.next.next = head
     head.next = None
     return p
    def reverseKGroup(self, head: ListNode, k: int) -> ListNode:
        """
         Common
        """
        dummy = ListNode(-1)
        p = dummy
        while True:
            count = k
            stack = []
            cur = head
            while count and cur:
                stack.append(cur)
                cur = cur.next
                count -= 1
            # 注意,目前tmp所在k+1位置
            # 说明剩下的链表不够k个,跳出循环
            if count:
                p.next = head
                break
            # 翻转操作
            while stack:
                p.next = stack.pop()
                p = p.next
            # 与剩下链表连接起来  不需要
            # p.next = cur
            head = cur

        return dummy.next
 def partition(self, head: ListNode, x: int) -> ListNode:
     dummy = ListNode(-1)
     right_dummy = ListNode(-1)
     cur = dummy
     right_cur = right_dummy
     while head:
         if head.val < x:
             cur.next = head
             cur = head
         else:
             right_cur.next = head
             right_cur = right_cur.next
         head = head.next
     right_cur.next = None
     cur.next = right_dummy.next
     return dummy.next
    def reverseKGroup(self, head: ListNode, k: int) -> ListNode:
        """
        TODO :
        尾插法。

        Recurse
        """
        cur = head
        # print("HEAD_RAW | ",cur)
        cnt = 0
        while cur and cnt != k:
            cur = cur.next
            cnt += 1
        # print("cur before recurse | ",head,cur,k)
        if cnt == k:
            cur = self.reverseKGroup(cur, k)
            # print("cur after recurse HEAD |",head,"\t\tCUR",cur)
            while cnt:
                tmp = head.next
                head.next = cur
                cur = head
                head = tmp
                cnt -= 1
            head = cur
        return head
Beispiel #21
0
 def numComponents(self, head: ListNode, G: List[int]) -> int:
     """
     TODO 题义转换
     我们对链表进行一次扫描,一个组件在链表中对应一段极长的连续节点,因此如果当前的节点在列表 G 中,
     并且下一个节点不在列表 G 中,我们就找到了一个组件的尾节点,可以将答案加 1
     """
     lookup = set(G)
     dummy = ListNode(-1)
     dummy.next = head
     cur = dummy
     result = 0
     while cur and cur.next:
         if cur.val not in lookup and cur.next.val in lookup:
             result += 1
         cur = cur.next
     return result
 def splitListToParts(self, root: ListNode, k: int) -> List[ListNode]:
     """Me"""
     if not root:
         return [None] * k
     n = 0
     cur = root
     while cur:
         n += 1
         cur = cur.next
     rest = n % k
     divide = n // k
     cur_pos = root
     # print(rest,divide)
     res = [ListNode(-1) for _ in range(k)]
     for i in range(k):
         ith_node = res[i % k]
         ith_node.next = cur_pos
         if not cur_pos:
             continue
         else:
             cnt = divide
             if rest > 0:
                 rest -= 1
                 cnt += 1
             for _ in range(cnt - 1):
                 cur_pos = cur_pos.next
             if cur_pos:
                 tmp = cur_pos.next
                 cur_pos.next = None
                 cur_pos = tmp
     return [x.next for x in res]
Beispiel #23
0
    def swapPairs(self, head: ListNode) -> ListNode:
        """ME"""
        if not (head and head.next):
            return head
        dummy = ListNode(-1)
        cur_head = dummy
        while head and head.next:
            now_tail = head.next.next
            cur_pre = head.next

            head.next = now_tail
            cur_pre.next = head

            cur_head.next = cur_pre
            cur_head = cur_head.next.next
            head = cur_pre.next.next
        return dummy.next
Beispiel #24
0
def test_solutions():
    head = ListNode.initList([3, 2, 0, -4])
    cur = head
    while cur.val != 0:
        cur = cur.next
    cur.next = head
    res = Solution().detectCycle(head)
    assert res.val == 3
def test_solution():
    l = ListNode.initList([3, 2, 0, -4])
    assert not Solution().hasCycle(l)
    cur = l
    while cur.next:
        cur = cur.next
    cur.next = l
    assert Solution().hasCycle(l)
    def insertionSortList(self, head: ListNode) -> ListNode:
        """TODO"""
        if not (head and head.next): return head

        dummy = ListNode(None)
        dummy.next = head
        cur, sorted_tail = head.next, head

        while cur:
            prev = dummy
            while prev.next.val < cur.val:
                prev = prev.next
            if prev == sorted_tail:
                cur, sorted_tail = cur.next, cur
            else:
                cur.next, prev.next, sorted_tail.next = prev.next, cur, cur.next
                cur = sorted_tail.next
        return dummy.next
    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
        dummy = ListNode(-1)
        ans = dummy
        carry = 0
        while l1 or l2:
            if l1:
                carry += l1.val
                l1 = l1.next
            if l2:
                carry += l2.val
                l2 = l2.next

            ans.next = ListNode(carry % 10)
            ans = ans.next
            carry //= 10
        if carry:
            ans.next = ListNode(carry)
        return dummy.next
Beispiel #28
0
 def mergeKLists(self, lists: List[ListNode]) -> ListNode:
     """
      O(N*logk) k是链表数目 ;LeetCode无法运行?
      O(n)
      """
     Q = PriorityQueue()
     for l in lists:
         if l:
             Q.put((l.val, l))
     dummyHead = ListNode(-1)
     cur_head = dummyHead
     while not Q.empty():
         val, node = Q.get()
         cur_head.next = ListNode(val)
         cur_head = cur_head.next
         node = node.next
         if node:
             Q.put((node.val, node))
     return dummyHead.next
 def listOfDepth(self, tree: TreeNode) -> List[ListNode]:
     res = []
     if not tree:
         return res
     stack = [tree]
     while stack:
         n = len(stack)
         head = ListNode(-1)
         cur = head
         for i in range(n):
             node = stack.pop(0)
             if node.left:
                 stack.append(node.left)
             if node.right:
                 stack.append(node.right)
             cur.next = ListNode(node.val)
             cur = cur.next
         res.append(head.next)
     return res
Beispiel #30
0
 def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
     cur = dum = ListNode(0)
     while l1 and l2:
         if l1.val < l2.val:
             cur.next, l1 = l1, l1.next
         else:
             cur.next, l2 = l2, l2.next
         cur = cur.next
     cur.next = l1 if l1 else l2
     return dum.next