def addTwoNumbers(self, l1, l2, p=0): """ :type l1: ListNode :type l2: ListNode :rtype: ListNode """ if l1 is None and l2 is None and p == 0: return None x = l1.val if l1 is not None else 0 y = l2.val if l2 is not None else 0 s = x + y + p if s >= 10: p = s // 10 s = s % 10 else: p = 0 node = ListNode(s) if l1 is not None and l2 is not None: node.next = self.addTwoNumbers(l1.next, l2.next, p) elif l1 is not None: node.next = self.addTwoNumbers(l1.next, None, p) elif l2 is not None: node.next = self.addTwoNumbers(None, l2.next, p) return node
def swapPairs(self, head: ListNode) -> ListNode: nil = ListNode(0) nil.next = head head = nil while head.next and head.next.next: p = head.next head.next = p.next p.next = head.next.next head.next.next = p head = head.next.next return nil.next
def swapPairs(self, head: ListNode) -> ListNode: """ 1 2 3 4 cur p p.next t=p.next.next 3 cur.next=p.next 2 p.next.next=p 2 1 p.next=t 2 1 3 >>> Solution().swapPairs(ListNode.from_num(1234)).to_number() 2143 >>> Solution().swapPairs(ListNode.from_num(12345)).to_number() 21435 """ if not head: return head dummy = ListNode(0) dummy.next = head cur = dummy p = dummy.next while p and p.next: t = p.next.next # 交换 cur.next = p.next p.next.next = p p.next = t cur = p # 后移 p = p.next return dummy.next
def reverseList(self, head: ListNode) -> ListNode: tail = head while tail and tail.next: tail = tail.next self.reverse(head) head.next = None return tail
def deleteDuplicates(self, head: ListNode) -> ListNode: """ 好久没有链表,还是链表亲切一些,可能是因为链表的题不会太难 题目要求的是如果重复就删除,而不是只留一个 0 1 2 3 3 4 4 5 pre cur nxt 不相等,后移 pre cur nxt pre cur nxt 相等,后移 nxt pre cur nxt,将 pre.next 连接到 nxt,同时移动 cur 和 nxt pre cur nxt,继续判断 cur 和 nxt >>> Solution().deleteDuplicates(ListNode.from_num(1233445)).to_number() 125 """ if not head: # 因为后面要取 head.next 所以提前判断 return head dummy = ListNode(0) dummy.next = head pre, cur, nxt = dummy, head, head.next while cur and nxt: if cur.val != nxt.val: # 不相等,后移 pre.next = cur pre, cur, nxt = cur, nxt, nxt.next else: while nxt and cur.val == nxt.val: # 相等,查找 nxt nxt = nxt.next pre.next = nxt if nxt: cur, nxt = nxt, nxt.next return dummy.next
def reverseList(self, head: ListNode) -> ListNode: """ 该解法是参照 https://leetcode.com/problems/reverse-linked-list/discuss/323687/9-lines-java-code.-time-less-than-100-space-less-than-almost-100 ListNode tail = null; ListNode temp; while (head != null) { temp = head.next; head.next = tail; tail = head; head = temp; } return tail; >>> Solution().reverseList(ListNode.create()) 5 -> 4 -> 3 -> 2 -> 1 >>> Solution().reverseList(ListNode.create(0)) >>> a=1 >>> b=2 >>> c=3 >>> a,b,c=b,c,a >>> print(a,b,c) 2 3 1 """ pre = None while head: # 断开并指向前 pre # pre 后移,head 后移 head.next, pre, head = pre, head, head.next return pre
def reverseList(self, head: ListNode) -> ListNode: """ 该解法是参照 https://leetcode.com/problems/reverse-linked-list/discuss/323687/9-lines-java-code.-time-less-than-100-space-less-than-almost-100 ListNode tail = null; ListNode temp; while (head != null) { temp = head.next; head.next = tail; tail = head; head = temp; } return tail; >>> Solution().reverseList(ListNode.create()) 5 -> 4 -> 3 -> 2 -> 1 >>> Solution().reverseList(ListNode.create(0)) """ pre = None while head: # 断开并指向前一个 next = head.next # 移动指针 head.next, pre, head = pre, head, next # pre 是 head 的前一个,退出循环时,head 为空,所以是返回 pre return pre
def oddEvenList(self, head: ListNode) -> ListNode: if head is None: return None nil = ListNode(-1) nil.next = head f = head.next while f is not None and f.next is not None: p = f.next f.next = p.next p.next = head.next head.next = p head = head.next f = f.next return nil.next
def insertionSortList(self, head: ListNode) -> ListNode: if head is None: return head nil = ListNode(0) nil.next = head rest = head.next head.next = None while rest is not None: p = rest rest = rest.next pre, cur = nil, nil.next while cur is not None and cur.val <= p.val: cur = cur.next pre = pre.next p.next = cur pre.next = p return nil.next
def mergeTwoLists(self, l1, l2): """ :type l1: ListNode :type l2: ListNode :rtype: ListNode """ if l1 is None: return l2 if l2 is None: return l1 if l1.val < l2.val: node = ListNode(l1.val) node.next = self.mergeTwoLists(l1.next, l2) else: node = ListNode(l2.val) node.next = self.mergeTwoLists(l1, l2.next) return node
def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode: """ https://leetcode.com/problems/merge-two-sorted-lists/discuss/9735/Python-solutions-(iteratively-recursively-iteratively-in-place). 思路简单,next 为后续合并 >>> Solution().mergeTwoLists(ListNode.create(),ListNode.create(start=2)).trim() '1223344556' >>> Solution().mergeTwoLists(ListNode.create(start=2),ListNode.create()).trim() '1223344556' """ if not l1: # 也包含 l1 l2 均为空,此时返回空 return l2 if not l2: return l1 if l1.val < l2.val: l1.next = self.mergeTwoLists(l1.next, l2) return l1 else: l2.next = self.mergeTwoLists(l1, l2.next) return l2
def reverseKGroup(self, head: ListNode, k: int) -> ListNode: """ 前一题的扩展 这样的 S(n) 是 O(k) 不是 O(1) 1 记数反转 dummy 1 2 3 4 pre right pre right pre right 执行反转 left left.next t 2 1 3 4 left left.next t dummy 2 1 3 4 pre right pre right 太乱了,太难理解了,不调试都无法正常运行,参考答案重新修改 >>> Solution().reverseKGroup(ListNode.from_num(12345),2).to_number() 21435 >>> Solution().reverseKGroup(ListNode.from_num(12345),3).to_number() 32145 """ dummy = ListNode(0) dummy.next = head pre = dummy right = head while True: i = 1 while right and i < k: # 后移 k-1 次,所以 i 初值为 1 i += 1 right = right.next if i == k and right is not None: # 反转 left 到 right left = h = pre.next for _ in range(k - 1): # 从 pre.next 开始反转 k-2 次 t = left.next.next # 持有第三个 left.next.next = h # 2接上头 h = left.next # 此时 2 变为头 left.next = t # 1接上3,left 不用移动,他的 next 已经变化 pre.next = h # pre 接上 头 pre = left # pre 置到最后一个 right = left.next else: return dummy.next
def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode: nil = ListNode(0) nil.next = head def dfs(prev, cur): if cur is None: return 1 idx = dfs(cur, cur.next) print(cur.val, idx) if idx == n: prev.next = cur.next return idx + 1 dfs(nil, head) return nil.next
def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode: num_nodes = 0 counter = head dummy = ListNode() dummy.next = head curr = dummy while counter: num_nodes += 1 counter = counter.next for _ in range(0, num_nodes - n): curr = curr.next # stop before the element to be removed prev = curr tmp = curr.next.next prev.next = tmp return dummy.next
def reverseBetween(self, head: ListNode, m: int, n: int) -> ListNode: if m == n: return head dummy = ListNode() dummy.next = head pre = dummy for _ in range(m - 1): pre = pre.next # we need to connect m -> n+1 and m-1 to n after we reverse reverse = None cur = pre.next # First element to be rotated, m-th element for _ in range(n - m + 1): next = cur.next cur.next = reverse reverse = cur cur = next pre.next.next = cur pre.next = reverse return dummy.next
def reverseBetween(self, head, m, n): fakehead = ListNode(0) fakehead.next = head first = fakehead n -= m while m != 1: first = first.next m -= 1 if first is None or first.next is None: return head slow, fast = first.next, first.next.next while n > 0: next = fast.next fast.next = slow slow = fast fast = next n -= 1 first.next.next = fast first.next = slow return fakehead.next
def insertionSortList(self, head: ListNode) -> ListNode: if not head: return head dummy = ListNode(0) dummy.next = head lastSorted = head cur = head.next while cur: if lastSorted.val <= cur.val: lastSorted = cur else: prev = dummy while prev.next.val <= cur.val: prev = prev.next lastSorted.next = cur.next cur.next = prev.next prev.next = cur cur = lastSorted.next return dummy.next
def deleteDuplicates(self, head: ListNode) -> ListNode: """ 好久没有链表,还是链表亲切一些,可能是因为链表的题不会太难 题目要求的是如果重复就删除,而不是只留一个 0 1 2 3 3 4 4 5 pre cur nxt 不相等,后移 pre cur nxt pre cur nxt 相等,后移 nxt pre cur nxt,将 pre.next 连接到 nxt,同时移动 cur 和 nxt pre cur nxt,继续判断 cur 和 nxt 1 不需要持有 next 0 1 2 3 3 4 4 5 pre cur 后移 pre cur pre cur 相等,后移 cur pre cur,将 pre.next 指向 cur.next,同时 cur 也后移 pre cur,同样相等,后移 cur pre cur,pre.next 指向 5,后移 cur pre cur,结束,后移 pre cur >>> Solution().deleteDuplicates(ListNode.from_num(1233445)).to_number() 125 """ dummy = ListNode(0) dummy.next = head pre, cur = dummy, head while cur: if cur.next and cur.val == cur.next.val: while cur.next and cur.val == cur.next.val: # 后移 cur = cur.next pre.next = cur.next # 如果有效,pre 会移动到 pre.next,否则,会重新赋值 pre.next cur = cur.next else: # 不相等,后移 pre = pre.next cur = cur.next return dummy.next
def deleteDuplicates(self, head: ListNode) -> ListNode: while head and head.next and head.next.val == head.val: while head.next and head.next.val == head.val: if head.next.next: head.next = head.next.next else: break head = head.next current = head while current: if current.next and current.next.next and current.next.val == current.next.next.val: spec = current.next.val next_item = current.next while next_item and next_item.val == spec: next_item = next_item.next current.next = next_item current = current.next return head
def reverse_group(head: ListNode, k: int) -> ListNode: if not head or k < 2: return head dummy = ListNode(-1) dummy.next = head pre, end = dummy, dummy while end.next: for _ in range(k): if end: end = end.next else: break if not end: return dummy.next start, nxt, end.next = pre.next, end.next, None pre.next = reverse_list(start) start.next, pre, end = nxt, start, start return dummy.next
def deleteDuplicates(self, head): if head is None: return None cur = head head = ListNode(0) head.next = cur par = head is_dup = False while cur.next != None: if cur.next.val == cur.val: cur.next = cur.next.next is_dup = True else: if is_dup: par.next = cur.next is_dup = False else: par = par.next cur = cur.next if is_dup: par.next = None return head.next
def reverseBetween(self, head: ListNode, m: int, n: int) -> ListNode: """ 旋转一部分,考虑参数异常情况 借助调试,居然过了,觉复有些复杂,去看讨论 >>> Solution().reverseBetween(ListNode.from_num(12345),2,4).to_number() 14325 """ if m >= n: return head dummy = ListNode(0) dummy.next = head i = 0 pre, cur = dummy, dummy.next reverse_pre = reverse_end = None while cur: i += 1 if i < m: pre = cur cur = cur.next elif i == m: # 开始记录 reverse_pre = pre reverse_end = cur t = cur.next cur.next = None pre = cur cur = t elif i < n: # 翻转 t = cur.next cur.next = pre pre = cur cur = t else: # 结束翻转 t = cur.next cur.next = pre reverse_pre.next = cur reverse_end.next = t break return dummy.next
def new_node(val, next): node = ListNode(val) node.next = next return node
Do not return anything, modify head in-place instead. """ self.head = head self.dfs(head) def dfs(self, node): if node is None: return True if self.dfs(node.next): if self.head != node and self.head.next != node: node.next = self.head.next self.head.next = node self.head = node.next return True else: node.next = None return False return False head = ListNode(1) head.next = ListNode(2) head.next.next = ListNode(3) Solution().reorderList(head) while head is not None: print( head.val, ' ', ) head = head.next