def addTwoNumbers(l1: ListNode, l2: ListNode) -> ListNode: #栈1 stack1 = [] while l1: stack1.append(l1) l1 = l1.next #栈2 stack2 = [] while l2: stack2.append(l2) l2 = l2.next #求和 carry = 0 # stack3 = [] head = None while len(stack1) or len(stack2) or carry: x = stack1.pop().val if len(stack1) else 0 y = stack2.pop().val if len(stack2) else 0 sum = x + y + carry # stack3.append(ListNode(sum % 10)) node = ListNode(sum % 10) node.next = head head = node carry = sum // 10 #结果栈 # dummy = ListNode(0) # cur = dummy # while len(stack3): # cur.next = stack3.pop() # cur = cur.next # return dummy.next return head
def insertionSortList1(head: ListNode) -> ListNode: if not head: return head dummy = ListNode() dummy.next = head cur_pre = head cur = head.next while cur: # 直接下一个 if cur.val >= cur_pre.val: cur_pre = cur cur = cur.next else: # 一定会有一个比cur大的节点 h = dummy.next greater = None while h and h.next != cur: if cur.val >= h.val and cur.val <= h.next.val: # 记录先不交换 greater = h h = h.next temp = cur.next # 插入cur if greater: cur.next = greater.next greater.next = cur else: cur.next = dummy.next dummy.next = cur # 删除cur cur = temp cur_pre.next = cur return dummy.next
def sortList2(head: ListNode) -> ListNode: """down2up""" h, length, intv = head, 0, 1 while h: h, length = h.next, length + 1 res = ListNode(0) res.next = head # merge the list in different intv. while intv < length: pre, h = res, res.next while h: # get the two merge head `h1`, `h2` h1, i = h, intv while i and h: h, i = h.next, i - 1 if i: break # no need to merge because the `h2` is None. h2, i = h, intv while i and h: h, i = h.next, i - 1 c1, c2 = intv, intv - i # the `c2`: length of `h2` can be small than the `intv`. # merge the `h1` and `h2`. while c1 and c2: if h1.val < h2.val: pre.next, h1, c1 = h1, h1.next, c1 - 1 else: pre.next, h2, c2 = h2, h2.next, c2 - 1 pre = pre.next pre.next = h1 if c1 else h2 while c1 > 0 or c2 > 0: pre, c1, c2 = pre.next, c1 - 1, c2 - 1 pre.next = h intv *= 2 return res.next
def reverseKGroup1(head: ListNode, k: int) -> ListNode: def reverse(head, tail): """翻转一个子链表,并且返回新的头与尾""" prev = tail.next p = head while prev != tail: nex = p.next p.next = prev prev = p p = nex return tail, head dummyNode = ListNode(0) dummyNode.next = head pre = dummyNode while head: tail = pre # 查看剩余部分长度是否大于等于 k for _ in range(k): tail = tail.next if not tail: return dummyNode.next nex = tail.next head, tail = reverse(head, tail) # 把子链表重新接回原链表 pre.next = head tail.next = nex pre = tail head = tail.next return dummyNode.next
def insertionSortList2(head: ListNode) -> ListNode: if not head: return head dummy = ListNode() dummy.next = head cur_pre = head cur = head.next while cur: # 直接下一个 if cur.val >= cur_pre.val: cur_pre = cur cur = cur.next else: # 一定会有一个比cur大的节点 greater_pre = dummy while greater_pre.next.val <= cur.val: greater_pre = greater_pre.next #这是和官方有出入的地方 temp = cur.next #插入 cur.next = greater_pre.next greater_pre.next = cur #下一个 cur = temp cur_pre.next = cur return dummy.next
def deleteNode(node: ListNode): """ :type node: ListNode :rtype: void Do not return anything, modify node in-place instead. """ #不能删除当前节点,那就交换下一个节点的值然后删除下一个节点 node.val = node.next.val node.next = node.next.next
def main(): node1 = ListNode(1) node2 = ListNode(2) node1.next = node2 node3 = ListNode(2) node2.next = node3 node4 = ListNode(1) node3.next = node4 ret = isPalindrome(node1) print(ret)
def mergeTwoLists(l1: ListNode, l2: ListNode) -> ListNode: if l1 is None: return l2 elif l2 is None: return l1 elif l1.val < l2.val: l1.next = mergeTwoLists(l1.next, l2) return l1 else: l2.next = mergeTwoLists(l1, l2.next) return l2
def deleteDuplicates_skill(head: ListNode) -> ListNode: """skill解法:重点已排序,哑结点""" dummy = ListNode(0) dummy.next = head ptr = dummy while ptr.next and ptr.next.next: if ptr.next.val == ptr.next.next.val: ptr.next = ptr.next.next else: ptr = ptr.next return dummy.next
def swapPairs2(head: ListNode) -> ListNode: dummyHead = ListNode(0) dummyHead.next = head temp = dummyHead while temp.next and temp.next.next: node1 = temp.next node2 = temp.next.next temp.next = node2 node1.next = node2.next node2.next = node1 temp = node1 return dummyHead.next
def deleteNode(head: ListNode, val: int) -> ListNode: dummy = ListNode(0) dummy.next = head pre = dummy cur = head while cur: if cur.val == val: pre.next = cur.next cur = pre.next else: pre = cur cur = cur.next return dummy.next
def removeElements(head: ListNode, val: int) -> ListNode: """模拟题:直接遍历/不用pre节点需要处理end""" dummy = ListNode(0) dummy.next = head pre = dummy cur = head while cur: if cur.val == val: pre.next = cur.next cur = pre.next else: pre = cur cur = cur.next return dummy.next
def partition(head: ListNode, x: int) -> ListNode: biggerHead = bigger = ListNode() smallerHead = smaller = ListNode() while head: if head.val < x: smaller.next = head smaller = smaller.next else: bigger.next = head bigger = bigger.next head = head.next smaller.next = biggerHead.next bigger.next = None return smallerHead.next
def main(): node1 = ListNode(4) node2 = ListNode(5) node1.next = node2 node3 = ListNode(1) node2.next = node3 node4 = ListNode(9) node3.next = node4 deleteNode(node2) head = node1 while head: print(head.val) head = head.next
def mergeKLists(lists: List[ListNode]) -> ListNode: """ 优先队列: 元组比较:https://leetcode-cn.com/problems/merge-k-sorted-lists/solution/leetcode-23-he-bing-kge-pai-xu-lian-biao-by-powcai/ vs 自定义比较函数 """ def __lt__(self, other): return self.val < other.val ListNode.__lt__ = __lt__ import heapq heap = [] for l in lists: if l: heapq.heappush(heap, l) dummy = ListNode(0) p = dummy while heap: node = heapq.heappop(heap) p.next = node p = p.next if node.next: heapq.heappush(heap, node.next) return dummy.next
def mergeTwoLists1(l1: ListNode, l2: ListNode) -> ListNode: """拓展思路:递归实现""" dummyNode = ListNode(0) result = dummyNode while l1 and l2: if l1.val > l2.val: result.next = l2 l2 = l2.next else: result.next = l1 l1 = l1.next result = result.next # 合并后 l1 和 l2 最多只有一个还未被合并完,我们直接将链表末尾指向未合并完的链表即可 result.next = l1 if l1 is not None else l2 # while l1: # result.next = l1 # l1 = l1.next # result = result.next # # while l2: # result.next = l2 # l2 = l2.next # result = result.next return dummyNode.next
def swapPairs(head: ListNode) -> ListNode: """递归""" if not head or not head.next: return head newHead = head.next head.next = swapPairs(newHead.next) newHead.next = head return newHead
def deleteDuplicates(head: ListNode) -> ListNode: """解法:重点已排序""" dummy = ListNode(0) dummy.next = head pre, ptr = dummy, head while ptr and ptr.next: dup = False # 找到重复值子链表的最后一个节点 while ptr and ptr.next and ptr.val == ptr.next.val: dup = True ptr = ptr.next if dup: ptr = ptr.next pre.next = ptr else: pre = ptr ptr = ptr.next return dummy.next
def removeZeroSumSublists(head: ListNode) -> ListNode: """前缀和+hashmap:sum相同的节点后面会覆盖前面,二次遍历间接删除了sum=0的节点""" dummy = ListNode(0) dummy.next = head sum_map = dict() p, sum_value = dummy, 0 while p: sum_value += p.val sum_map[sum_value] = p p = p.next p, sum_value = dummy, 0 while p: sum_value += p.val p.next = sum_map[sum_value].next p = p.next return dummy.next
def deleteDuplicates_naive(head: ListNode) -> ListNode: """朴素解法:hash表""" if not head or not head.next: return head ptr, map = head, {} while ptr: if ptr.val not in map: map[ptr.val] = 0 else: map[ptr.val] += 1 ptr = ptr.next dummy = ListNode(0) dummy.next = head ptr = dummy while ptr.next: if map[ptr.next.val] > 0: ptr.next = ptr.next.next else: ptr = ptr.next return dummy.next
def reverseKGroup(head: ListNode, k: int) -> ListNode: """图解k个一组翻转链表: 一图胜千言:https://leetcode-cn.com/problems/reverse-nodes-in-k-group/solution/tu-jie-kge-yi-zu-fan-zhuan-lian-biao-by-user7208t/ """ def reverse(head): """翻转链表""" pre = None cur = head while cur: temp = cur.next cur.next = pre pre = cur cur = temp return pre dummyNode = ListNode(0) dummyNode.next = head # 初始pre/end pre = dummyNode end = pre while end.next: for _ in range(k): end = end.next if not end: return dummyNode.next #记录start start = pre.next #记录next next = end.next #断开k区间的链表 end.next = None #翻转 pre.next = reverse(start) #拼接翻转之后的k区间 start.next = next #重置pre/end pre = start end = pre return dummyNode.next
def insertionSortList(head: ListNode) -> ListNode: """对于单向链表而言,只有指向后一个节点的指针,因此需要从链表的头节点开始往后遍历链表中的节点,寻找插入位置。""" if not head: return head dummyHead = ListNode(0) dummyHead.next = head lastSorted = head curr = head.next while curr: if lastSorted.val <= curr.val: lastSorted = lastSorted.next else: prev = dummyHead while prev.next.val <= curr.val: prev = prev.next lastSorted.next = curr.next curr.next = prev.next prev.next = curr curr = lastSorted.next return dummyHead.next
def addTwoNumbers(l1: ListNode, l2: ListNode) -> ListNode: pre = ListNode(0) cur = pre carry = 0 while l1 or l2 or carry: x = l1.val if l1 else 0 y = l2.val if l2 else 0 sum = x + y + carry cur.next = ListNode(sum % 10) cur = cur.next if l1: l1 = l1.next if l2: l2 = l2.next # 牛逼2 // -> if # carry = sum // 10 carry = 1 if sum > 9 else 0 # 牛逼1 or carry # if carry: cur.next = ListNode(carry) return pre.next
def swapPairs1(head: ListNode) -> ListNode: """迭代""" dummyNode = ListNode(0) p = dummyNode while head: cur = head if cur.next: head = cur.next.next cur.next.next = cur p.next = cur.next p = p.next.next p.next = None else: p.next = cur head = None return dummyNode.next
def sortList(head: ListNode) -> ListNode: """快速排序或者归并排序""" if not head or not head.next: return head # termination. # cut the LinkedList at the mid index. slow, fast = head, head.next while fast and fast.next: fast, slow = fast.next.next, slow.next mid, slow.next = slow.next, None # save and cut. # recursive for cutting. left, right = sortList(head), sortList(mid) # merge `left` and `right` linked list and return it. h = res = ListNode(0) while left and right: if left.val < right.val: h.next, left = left, left.next else: h.next, right = right, right.next h = h.next h.next = left if left else right return res.next
def reverseBetween(head: ListNode, m: int, n: int) -> ListNode: ptr, head_ptr = head, None while m > 1: m -= 1 n -= 1 head_ptr = head head = head.next between_tail = between_ptr = head while n > 0: n -= 1 temp = head.next head.next = between_ptr between_ptr = head head = temp between_tail.next = head if head_ptr is None: ptr = between_ptr else: head_ptr.next = between_ptr return ptr
def main(): node1 = ListNode(3) node2 = ListNode(2) node1.next = node2 node3 = ListNode(0) node2.next = node3 node4 = ListNode(-4) node3.next = node4 # node5 = ListNode(2) # node4.next = node5 # 链表成环 node4.next = node2 #相交节点-4,入环节点2,环长度3 ret = detectCycle(node1) if ret: print(ret.val) else: print(None)
def main(): node1 = ListNode(2) node2 = ListNode(4) node1.next = node2 node3 = ListNode(3) node2.next = node3 l1 = node1 node1 = ListNode(5) node2 = ListNode(6) node1.next = node2 node3 = ListNode(4) node2.next = node3 l2 = node1 ret = addTwoNumbers(l1, l2) while (ret): print(ret.val) ret = ret.next
def main(): node1 = ListNode(3) node2 = ListNode(2) node1.next = node2 node3 = ListNode(0) node2.next = node3 node4 = ListNode(-4) node3.next = node4 # node5 = ListNode(2) # node4.next = node5 node4.next = node2 ret = hasCycle(node1) print(ret)
def main(): # 相交部分 node1 = ListNode(8) node2 = ListNode(4) node1.next = node2 node3 = ListNode(5) node2.next = node3 # A headA = ListNode(4) nodeA1 = ListNode(1) headA.next = nodeA1 nodeA1.next = node1 # head = headA # while head: # print(head.val) # head = head.next # B headB = ListNode(5) nodeB1 = ListNode(0) headB.next = nodeB1 nodeB2 = ListNode(1) nodeB1.next = nodeB2 nodeB2.next = node1 # head = headB # while head: # print(head.val) # head = head.next """ my_list_node = MyListNode() my_list_node.addAtTail(4) my_list_node.addAtTail(1) my_list_node.addAtTail(8) my_list_node.addAtTail(4) my_list_node.addAtTail(5) headA = my_list_node.head my_list_node = MyListNode() my_list_node.addAtTail(5) my_list_node.addAtTail(0) my_list_node.addAtTail(1) my_list_node.addAtTail(8) my_list_node.addAtTail(4) my_list_node.addAtTail(5) headB = my_list_node.head """ ret = getIntersectionNode(headA, headB) if ret: print(ret.val) else: print(None)