def reverseList(self, head: ListNode) -> ListNode: if head is None or head.next is None: return head node = self.reverseList(head.next) head.next.next = head head.next = None return node
def sortList(self, head: ListNode) -> ListNode: # 递归终点 if not head or not head.next: return head # 中点寻找 slow = head fast = head.next # 否则爆栈 while fast and fast.next: slow = slow.next fast = fast.next.next mid = slow.next slow.next = None # 处理左链表与右链表 left = self.sortList(head) right = self.sortList(mid) # 合并两个排序连败哦 dummy = dp = ListNode(0) while left and right: if left.val < right.val: dp.next = left left = left.next else: dp.next = right right = right.next dp = dp.next dp.next = left if left else right return dummy.next
def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode: dummy = ListNode(0) node = dummy carry = 0 while l1 or l2 or carry != 0: if l1: carry += l1.val l1 = l1.next if l2: carry += l2.val l2 = l2.next carry, rem = divmod(carry, 10) node.next = ListNode(rem) node = node.next return dummy.next
def removeNthFromEnd(self, head, n): """ :type head: ListNode :type n: int :rtype: ListNode """ mock_head = ListNode(-1) mock_head.next = head pre = mock_head tail = mock_head while n: pre = pre.next n -= 1 while pre and pre.next: pre = pre.next tail = tail.next tail.next = tail.next.next return mock_head.next
def Merge(self, pHead1, pHead2): # write code here if pHead1 is None: return pHead2 elif pHead2 is None: return pHead1 dummy = ListNode(-1) cur = dummy while pHead1 and pHead2.val: if pHead1.val > pHead2: cur.next = ListNode(pHead1.val) pHead1 = pHead1.next else: cur.next = ListNode(pHead2.val) pHead2 = pHead2.next cur = cur.next if pHead1: cur.next = pHead1 else: cur.next = pHead2 return dummy.next
def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode: dummy = ListNode(0, 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 merge(h1: ListNode, h2: ListNode): p1, p2, dummy = h1, h2, ListNode(0) dp = dummy while p1 and p2: if p1.val < p2.val: dp.next = p1 p1 = p1.next else: dp.next = p2 p2 = p2.next dp = dp.next dp.next = p1 if p1 else p2 return dummy.next
def mergeKLists(self, lists: List[ListNode]) -> ListNode: my_lists = [MyNode(node) for node in lists] heapq.heapify(my_lists) dummy = ListNode(0) p = dummy while my_lists: node = heapq.heappop(my_lists).node p.next = node p = p.next if node.next: heapq.heappush(my_lists, MyNode(node.next)) p.next = None return dummy.next
def merge(a: ListNode, b: ListNode): dummy = ListNode(0) dp = dummy while a and b: if a.val < b.val: dp.next = a a = a.next else: dp.next = b b = b.next dp = dp.next dp.next = a if a else b return dummy.next
def insertionSortList(self, head: ListNode) -> ListNode: if not head: return head dummy = ListNode(-inf) # D dummy.next = head # D 4 2 1 3 ∅ tail = dummy.next # 4 ∅ // 如果新结点比【有序区】的【尾结点】更大,直接成为新的尾结点 p = head.next # 2 1 3 ∅ // 头结点的第一个元素初始为【有序区】,从头结点的【下一个元素】开始遍历 tail.next = None # 封闭有序区 while p: aft = p.next # 缓存下一个结点 if p.val >= tail.val: # 注意符号 tail.next = p tail = p else: dp = dummy while dp.next: # 首次出现比p大的元素。插入到那个元素前面 if dp.next.val > p.val: p.next = dp.next dp.next = p break dp=dp.next p = aft tail.next = None return dummy.next
def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode: head = ListNode(0) p = head while (l1 is not None) and (l2 is not None): if l1.val > l2.val: p.next = l2 l2 = l2.next else: p.next = l1 l1 = l1.next p = p.next if l1 is None: p.next = l2 if l2 is None: p.next = l1 return head.next
def swapPairs(self, head: ListNode) -> ListNode: if not head: return None dummy = ListNode() dp = dummy p = head while p: np = p.next if np: nnp = np.next dp.next = np dp = dp.next dp.next = p dp = dp.next p = nnp else: dp.next = p dp = dp.next break if dp: dp.next = None return dummy.next
def reverseBetween(self, head: ListNode, left: int, right: int) -> ListNode: # 以case 1, 2, 3, 4, 5 为例,left = 2, right = 4 p = head L = right - left + 1 # 翻转的部分是 2 3 4, 长度为3 dummy = ListNode(0) dp = dummy for _ in range(left - 1): # 把 翻转部分 2 之前的添加到dummy中(dummy用来返回) dp.next = p dp = dp.next p = p.next # 迭代完之后 p=2 aft = p.next pre = None l2_tail = p # 第二段(l2) 的开头,但翻转后会变成末尾 for _ in range(L): aft = p.next p.next = pre pre = p p = aft dp.next = pre # 接上翻转的列表, 即 1 4 3 2 l2_tail.next = aft # l2 段 接上剩下没迭代的 return dummy.next
def sortList(self, head: ListNode) -> ListNode: dummy = ListNode(0, head) p = head length = 0 while p: p = p.next length += 1 sub_len = 1 while sub_len < length: pre, cur = dummy, dummy.next while cur: h1 = cur for _ in range(sub_len - 1): if cur and cur.next: cur = cur.next else: break h2 = cur.next cur.next = None # h1 结扎 cur = h2 # 恢复 cur for _ in range(sub_len - 1): if cur and cur.next: cur = cur.next else: break suc = None if cur: # 构造新的【cur】 suc = cur.next cur.next = None # h2 结扎 cur = suc # merged = merge(h1, h2) pre.next = merged # 构造新的【pre】 (merged的最后一个结点) while pre.next: pre = pre.next sub_len *= 2 return dummy.next
# 递归终点 if not head or not head.next: return head # 中点寻找 slow = head fast = head.next # 否则爆栈 while fast and fast.next: slow = slow.next fast = fast.next.next mid = slow.next slow.next = None # 处理左链表与右链表 left = self.sortList(head) right = self.sortList(mid) # 合并两个排序连败哦 dummy = dp = ListNode(0) while left and right: if left.val < right.val: dp.next = left left = left.next else: dp.next = right right = right.next dp = dp.next dp.next = left if left else right return dummy.next ans = Solution().sortList(ListNode.fromList([1, 5, 3, 4, 0])) print(ans)
for _ in range(sub_len - 1): if cur and cur.next: cur = cur.next else: break h2 = cur.next cur.next = None # h1 结扎 cur = h2 # 恢复 cur for _ in range(sub_len - 1): if cur and cur.next: cur = cur.next else: break suc = None if cur: # 构造新的【cur】 suc = cur.next cur.next = None # h2 结扎 cur = suc # merged = merge(h1, h2) pre.next = merged # 构造新的【pre】 (merged的最后一个结点) while pre.next: pre = pre.next sub_len *= 2 return dummy.next print(Solution().sortList(ListNode.fromList([4, 2, 1, 3]))) # # print(merge(ListNode.fromList([1, 3, 5]), ListNode.fromList([2, 4, 6, 7])))
def insertionSortList(self, head: ListNode) -> ListNode: if not head: return head dummy = ListNode(-inf) # D dummy.next = head # D 4 2 1 3 ∅ tail = dummy.next # 4 ∅ // 如果新结点比【有序区】的【尾结点】更大,直接成为新的尾结点 p = head.next # 2 1 3 ∅ // 头结点的第一个元素初始为【有序区】,从头结点的【下一个元素】开始遍历 tail.next = None # 封闭有序区 while p: aft = p.next # 缓存下一个结点 if p.val >= tail.val: # 注意符号 tail.next = p tail = p else: dp = dummy while dp.next: # 首次出现比p大的元素。插入到那个元素前面 if dp.next.val > p.val: p.next = dp.next dp.next = p break dp=dp.next p = aft tail.next = None return dummy.next head = ListNode.fromList([4, 2, 1, 3]) ans = Solution().insertionSortList(head) print(ans)
from structure import ListNode class Solution: def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode: p = head k = 0 p2 = None while p is not None: p = p.next k += 1 if (k - 1) == n: p2 = head if (k - 1) > n: p2 = p2.next if p2 is None and k == n: head = head.next elif p2.next is not None: p2.next = p2.next.next return head if __name__ == '__main__': node = Solution().removeNthFromEnd(ListNode.fromList([1, 2]), 2) print(node)
def reverse(a, b): pre = None p = a while p != b: aft = p.next p.next = pre pre = p p = aft return pre class Solution: def reverseKGroup(self, head: ListNode, k: int) -> ListNode: if head is None: return None a = head b = head for _ in range(k): if b is None: return head b = b.next n_head = reverse(a, b) a.next = self.reverseKGroup(b, k) return n_head ans = Solution().reverseKGroup(ListNode.fromList([1, 2, 3, 4, 5]), 2) print(ans)
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Author : qichun tang # @Contact : [email protected] from structure import ListNode class Solution: def oddEvenList(self, head: ListNode) -> ListNode: if not head: return head oddHead, evenHead = head, head.next odd, even = oddHead, evenHead while even and even.next: odd.next = even.next odd = odd.next # 别忘了自己要移动 even.next = odd.next even = even.next odd.next = evenHead return head if __name__ == '__main__': nodes = ListNode.fromList([1, 2, 3, 4, 5]) solved = Solution().oddEvenList(nodes) print(solved)
from structure import ListNode class Solution: def reverseList(self, head: ListNode) -> ListNode: if head is None or head.next is None: return head node = self.reverseList(head.next) head.next.next = head head.next = None return node print(Solution().reverseList(ListNode.fromList([1, 2, 3, 4, 5])))
right: int) -> ListNode: # 以case 1, 2, 3, 4, 5 为例,left = 2, right = 4 p = head L = right - left + 1 # 翻转的部分是 2 3 4, 长度为3 dummy = ListNode(0) dp = dummy for _ in range(left - 1): # 把 翻转部分 2 之前的添加到dummy中(dummy用来返回) dp.next = p dp = dp.next p = p.next # 迭代完之后 p=2 aft = p.next pre = None l2_tail = p # 第二段(l2) 的开头,但翻转后会变成末尾 for _ in range(L): aft = p.next p.next = pre pre = p p = aft dp.next = pre # 接上翻转的列表, 即 1 4 3 2 l2_tail.next = aft # l2 段 接上剩下没迭代的 return dummy.next case1 = ListNode.fromList([3, 5]) ans = Solution().reverseBetween(case1, 1, 2) print(ans) # ans = Solution().reverseBetween(ListNode.fromList(list(range(1, 6))), 2, 4) # print(ans)
class Solution: def reorderList(self, head: ListNode) -> None: if head is None: return None p = head vec = [] while p is not None: vec.append(p) p = p.next i = 0 j = len(vec) - 1 while i < j: vec[i].next = vec[j] i += 1 if i == j: break vec[j].next = vec[i] j -= 1 vec[i].next = None # 容易想错 node = ListNode.fromList([1, 2, 3, 4]) Solution().reorderList(node) print(node) node = ListNode.fromList([1, 2, 3, 4, 5]) Solution().reorderList(node) print(node)
def prepare_case(self, case): params = case['params'] params[0] = ListNode(params[0]) params[1] = ListNode(params[1]) case['params'] = params case['expected'] = ListNode(case['expected'])
from structure import ListNode class Solution: def swapPairs(self, head: ListNode) -> ListNode: if not head: return None dummy = ListNode() dp = dummy p = head while p: np = p.next if np: nnp = np.next dp.next = np dp = dp.next dp.next = p dp = dp.next p = nnp else: dp.next = p dp = dp.next break if dp: dp.next = None return dummy.next print(Solution().swapPairs(ListNode.fromList([1])))
from structure import ListNode node = ListNode.fromList([1, 2]) def partition(head: ListNode): if not head or not head.next: return head p1, p2 = head, head.next head1, head2 = p1, p2 # p2 后面至少有1个结点 while p2 and p2.next: p1.next = p2.next p1 = p1.next p2.next = p1.next p2 = p2.next p1.next = None return head1, head2 print(partition(node))
from structure import ListNode class Solution: def isPalindrome(self, head: ListNode) -> bool: # hash = hash * seed + val # seed: prime number # val: node value # hash1 = a0 * seed^(n-1) + a1 * seed^(n-2) hash1 = hash2 = 0 h = 1 # seed=int(1e9+7) seed = 3 p = head while p is not None: hash1 = hash1 * seed + p.val hash2 = hash2 + h * p.val h *= seed p = p.next return hash1 == hash2 if __name__ == '__main__': node = ListNode.fromList([1, 2, 2, 1]) print(Solution().isPalindrome(node))
while fast and fast.next: slow = slow.next fast = fast.next.next # 反转链表 p = slow.next slow.next = None if p is None: return pre = None while p: aft = p.next p.next = pre pre = p p = aft # 合并链表 a, b = head, pre while True: an = a.next bn = b.next if b else None a.next = b if b: b.next = an a = an b = bn if not b: break node = ListNode.fromList([1]) Solution().reorderList(node) print(node)
if a.val < b.val: dp.next = a a = a.next else: dp.next = b b = b.next dp = dp.next dp.next = a if a else b return dummy.next def partition(lists): n = len(lists) if n == 0: return None elif n == 1: return lists[0] else: mid = len(lists) // 2 return merge(partition(lists[:mid]), partition(lists[mid:])) class Solution: def mergeKLists(self, lists: List[ListNode]) -> ListNode: return partition(lists) a = ListNode.fromList([1, 3, 5]) b = ListNode.fromList([2, 4]) print(merge(a, b))