Esempio n. 1
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)
Esempio n. 2
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 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
Esempio n. 4
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
Esempio n. 5
0
    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
        l1stack, l2stack = [], []
        while l1:
            l1stack.append(l1.val)
            l1 = l1.next
        while l2:
            l2stack.append(l2.val)
            l2 = l2.next
        len1, len2 = len(l1stack), len(l2stack)
        if len1 >= len2:
            long, short = l1stack, l2stack
        else:
            short, long = l1stack, l2stack
        i = 0
        carry = 0
        head_node, cur_node = None, None
        while i < len(short):
            v_sum = short[i] + long[i] + carry
            if v_sum >= 10:
                carry = 1
                v_sum = v_sum - 10
            else:
                carry = 0
            if not head_node:
                cur_node = ListNode(v_sum)
                head_node = cur_node
            else:
                next_node = ListNode(v_sum)
                cur_node.next = next_node
                cur_node = next_node

            i += 1
        while i < len(long):
            v_sum = long[i] + carry
            if v_sum >= 10:
                carry = 1
                v_sum = v_sum - 10
            else:
                carry = 0
            next_node = ListNode(v_sum)
            cur_node.next = next_node
            cur_node = next_node
            i += 1
        if carry:
            next_node = ListNode(carry)
            cur_node.next = next_node
        return head_node
Esempio n. 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
Esempio n. 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
 def mergeInBetween(self, list1: ListNode, a: int, b: int,
                    list2: ListNode) -> ListNode:
     start, end = None, list1
     for i in range(b):
         if i == a - 1:
             start = end
         end = end.next
     start.next = list2
     while list2.next:
         list2 = list2.next
     list2.next = end.next
     end.next = None
     return list1
 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
    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
Esempio n. 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
 def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
     stack1, stack2 = [], []
     while l1:
         stack1.append(l1.val)
         l1 = l1.next
     while l2:
         stack2.append(l2.val)
         l2 = l2.next
     prev, head = None, None
     sum = 0
     while stack1 or stack2:
         sum //= 10
         if stack1:
             sum += stack1.pop()
         if stack2:
             sum += stack2.pop()
         head = ListNode(sum % 10)
         head.next = prev
         prev = head
     if sum >= 10:
         head = ListNode(sum // 10)
         head.next = prev
     return head
 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
Esempio n. 15
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 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
Esempio n. 17
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
    def reverseList(self, head: ListNode) -> ListNode:
        """TODO
        涉及到链表的操作,一定要在纸上把过程先画出来,再写程序
        https://leetcode-cn.com/problems/reverse-linked-list/solution/fan-zhuan-lian-biao-by-leetcode/
        假设列表的其余部分已经被反转,现在我该如何反转它前面的部分
        如 N1->N2->..->Nk->N(k+1)<-..<-Nm<- ∅
        我们正处于Nk
        所以
        Nk.next.next=Nk

        """
        if not (head and head.next):
            return head
        p = self.reverseList(head.next)
        head.next.next = head
        head.next = None
        return p
    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 isPalindrome(self, head: ListNode) -> bool:
        reverse, fast = None, head
        # Reverse the first half part of the list.
        while fast and fast.next:
            fast = fast.next.next
            head.next, reverse, head = reverse, head, head.next
        # If the number of the nodes is odd,
        # set the head of the tail list to the next of the median node.
        tail = head.next if fast else head
        # print(head,reverse,tail)

        # Compare the reversed first half list with the second half list.
        # And restore the reversed first half list.
        while reverse:
            if reverse.val != tail.val:
                return False
            reverse.next, head, reverse = head, reverse, reverse.next
            tail = tail.next
        return True
Esempio n. 21
0
    def plusOne(self, head: ListNode) -> ListNode:
        """TODO"""

        def helper(node):
            if not node:
                return 1
            carry = helper(node.next)
            sum_val = carry + node.val
            node.val = sum_val % 10
            return sum_val // 10

        if not head:
            return head
        carry = helper(head)
        if carry:
            res = ListNode(1)
            res.next = head
            return res
        return head
Esempio n. 22
0
    def reverseBetween(self, head: ListNode, m: int, n: int) -> ListNode:
        """
        92
        :param head:
        :param m:
        :param n:
        :return:
        """
        if m == n:
            return head
        infix_tail = None
        infix_head = None
        node = None
        idx = 1
        while idx < m:
            if node is None:
                node = head
            else:
                node = node.next
            idx += 1
        prefix_tail = node

        while idx <= n:
            if node is None:
                node = head
            else:
                node = node.next
            infix_node = ListNode(node.val)
            if infix_head is None:
                infix_head = infix_tail = infix_node
            else:
                infix_node.next = infix_head
                infix_head = infix_node

            idx += 1
        if prefix_tail is None:
            new_head = infix_head
        else:
            new_head = head
            prefix_tail.next = infix_head
        infix_tail.next = node.next
        return new_head
    def reverseKGroup(self, head: ListNode, k: int) -> ListNode:
        hair = ListNode(-1)
        hair.next = head
        pre = hair

        while head:
            tail = pre
            # 查看剩余部分长度是否大于等于 k
            for i in range(k):
                tail = tail.next
                if not tail:
                    return hair.next
            tmp = tail.next
            head, tail = self.reverse(head, tail)
            # 把子链表重新接回原链表
            pre.next = head
            tail.next = tmp
            pre = tail
            head = tail.next

        return hair.next
Esempio n. 24
0
    def plusOne(self, head: ListNode) -> ListNode:
        # sentinel head
        sentinel = ListNode(0)
        sentinel.next = head
        not_nine = sentinel

        # find the rightmost not-nine digit
        while head:
            if head.val != 9:
                not_nine = head
            head = head.next

            # increase this rightmost not-nine digit by 1
        not_nine.val += 1
        not_nine = not_nine.next

        # set all the following nines to zeros
        while not_nine:
            not_nine.val = 0
            not_nine = not_nine.next

        return sentinel if sentinel.val else sentinel.next
Esempio n. 25
0
    def swapPairs(self, head: ListNode) -> ListNode:
        # Dummy node acts as the prevNode for the head node
        # of the list and hence stores pointer to the head node.
        dummy = ListNode(-1)
        dummy.next = head

        prev_node = dummy

        while head and head.next:
            # Nodes to be swapped
            first_node = head
            second_node = head.next

            # Swapping
            prev_node.next = second_node
            first_node.next = second_node.next
            second_node.next = first_node

            # Reinitializing the head and prev_node for next swap
            prev_node = first_node
            head = first_node.next

        # Return the new head node.
        return dummy.next
 def reverse(self, a: ListNode, b: ListNode):
     prev, cur = ListNode(-1), a
     while cur != b:
         prev.next, cur.next, cur = cur, prev.next, cur.next
     return prev.next
 def reverseList(self, head: ListNode) -> ListNode:
     dummy = ListNode(-1)
     cur = head
     while cur:
         dummy.next, cur.next, cur = cur, dummy.next, cur.next
     return dummy.next