def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode: """worst""" if l1 is None: return l2 if l2 is None: return l1 l1_node = l1 l2_node = l2 vals = [] while l1_node is not None: vals.append(l1_node.val) l1_node = l1_node.next while l2_node is not None: vals.append(l2_node.val) l2_node = l2_node.next vals = sorted(vals) return createList(vals)
for _ in range(mid_pos - 1): node = node.next return node def middleNode(self, head: ListNode) -> ListNode: """ Time O(n) Space O(1) """ slow = fast = head while fast and fast.next: slow = slow.next fast = fast.next.next return slow if __name__ == "__main__": s = Solution() data = [ ([1, 2, 3, 4, 5], 3), ([1, 2, 3, 4, 5, 6], 4), ([1], 1), ([1, 2], 2), ([1, 2, 3], 2), ] for it, gt in data: assert ( s.middleNode2(createList(it)).val == gt ), f"{it} {s.middleNode2(createList(it)).val} {gt}"
class Solution: def oddEvenList(self, head: ListNode) -> ListNode: if head is None: return None odd = head even = head.next evenHead = even while even is not None and even.next is not None: odd.next = even.next odd = odd.next even.next = odd.next even = even.next odd.next = evenHead return head if __name__ == "__main__": s = Solution() head = createList([1, 2, 3, 4, 5]) out = s.oddEvenList(head) assert compareList(out, [1, 3, 5, 2, 4]) head = createList([2, 1, 3, 5, 6, 4, 7]) out = s.oddEvenList(head) assert compareList(out, [2, 3, 6, 7, 1, 5, 4])
Time: O(n) Space: O(1) """ curr = head while (curr is not None) and (curr.next is not None): if curr.val != curr.next.val: curr = curr.next else: # curr 不动,只改 curr 的 next,相当于跳过了当中一个 curr.next = curr.next.next return head if __name__ == '__main__': s = Solution() l1 = createList([1]) assert compareList(s.deleteDuplicates(l1), [1]) == True l1 = createList([1, 1, 2]) assert compareList(s.deleteDuplicates(l1), [1, 2]) == True l1 = createList([1, 1, 2, 3, 3]) assert compareList(s.deleteDuplicates(l1), [1, 2, 3]) == True l1 = createList([1, 2, 3, 4, 5]) assert compareList(s.deleteDuplicates(l1), [1, 2, 3, 4, 5]) == True l1 = createList([1, 1, 1, 1, 1]) assert compareList(s.deleteDuplicates(l1), [1]) == True l1 = createList([1])
if n == 1: self.successor = head.next return head last = self.reverseN(head.next, n - 1) head.next.next = head head.next = self.successor return last def reverseBetween(self, head: Optional[ListNode], left: int, right: int) -> Optional[ListNode]: """ OMG! https://leetcode.com/problems/reverse-linked-list-ii/solution/242639 Time: O(n) Space: O(1) """ if left == 1: reversed_N = self.reverseN(head, right) return reversed_N head.next = self.reverseBetween(head.next, left - 1, right - 1) return head if __name__ == "__main__": s = Solution() data = [ ([1, 2, 3, 4, 5], 2, 4, [1, 4, 3, 2, 5]), ] for it, l, r, gt in data: assert compareList(s.reverseBetween(createList(it), l, r), gt) is True
class Solution: def reverseList(self, head: ListNode) -> ListNode: """ Time: O(n) Space: O(1) """ last_node = None while head is not None: next_head = head.next head.next = last_node last_node = head head = next_head return last_node if __name__ == "__main__": s = Solution() data = [ [1], [1, 2], [1, 2, 3], [1, 2, 3, 4, 5], ] for it in data: it_reversed = it.copy() it_reversed.reverse() assert compareList(s.reverseList(createList(it)), it_reversed) is True
slow.next = slow_head slow_head = slow slow = next_slow_head while slow_head: if slow_head.val != head.val: return False slow_head = slow_head.next head = head.next return True if __name__ == "__main__": s = Solution() head = createList([1, 2, 2, 1]) assert s.isPalindrome(head) == True head = createList([1, 2, 2]) assert s.isPalindrome(head) == False head = createList([2, 2]) assert s.isPalindrome(head) == True assert s.isPalindrome(None) == True head = createList([1]) assert s.isPalindrome(head) == True head = createList([1, 2, 2, 1]) assert s.isPalindrome2(head) == True
def compare(s, l1, l2, result): l1 = createList(l1) l2 = createList(l2) out = s.addTwoNumbers(l1, l2) print(out) assert compareList(out, result) == True
# @Time : 2020/10/23 11:13 # @Author : LiuBin # @File : 234.py # @Description : # @Software: PyCharm """回文链表 关键字: 栈 思路: 1、利用栈记录链表的倒序序列 2、依次比较栈和链表的值是否相等即可 """ from utils import ListNode, createList class Solution: def isPalindrome(self, head: ListNode) -> bool: stack = [] root = head while head: stack.append(head.val) head = head.next while root: if stack.pop() != root.val: return False root = root.next return True print(Solution().isPalindrome(createList([1, 2, 1])))
# Space: O(1) dummy = cur = 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 or l2 return dummy.next if __name__ == '__main__': s = Solution() l1 = createList([1, 2, 4]) l2 = createList([1, 3, 4]) assert compareList(l2, [1, 3, 4]) == True assert compareList(l2, [1, 2, 4]) == False assert compareList(s.mergeTwoLists1(l1, l2), [1, 1, 2, 3, 4, 4]) == True l1 = createList([1, 2, 4]) l2 = createList([1]) assert compareList(s.mergeTwoLists1(l1, l2), [1, 1, 2, 4]) == True l1 = createList([1, 2, 4]) l2 = createList([5]) assert compareList(s.mergeTwoLists1(l1, l2), [1, 2, 4, 5]) == True
def test(l1, l2, result): l1 = createList(l1) l2 = createList(l2) assert compareList(s.addTwoNumbers(l1, l2), result) == True
break else: head = head.next prev = None curr = head while curr is not None: if curr.val == val: # prev 为 head 的引用,这一步相当于在原始 llinked list 上操作 prev.next = curr.next curr = curr.next else: prev = curr curr = curr.next return head if __name__ == "__main__": s = Solution() head = createList([1, 2, 6, 3, 4, 5, 6]) out = s.removeElements(head, 6) assert compareList(out, [1, 2, 3, 4, 5]) head = createList([6, 2, 6, 3, 4, 5, 6]) out = s.removeElements(head, 6) assert compareList(out, [2, 3, 4, 5]) head = createList([6, 6, 6]) out = s.removeElements(head, 6) assert compareList(out, [])
# if they meet, pa or pb would be the node we are looking for, # if they didn't meet, they will hit the end at the same iteration, pa == pb == None, return either one of them is the same,None if headA is None or headB is None: return None pa = headA # 2 pointers pb = headB while pa is not pb: # if either pointer hits the end, switch head and continue the second traversal, # if not hit the end, just move on to next pa = headB if pa is None else pa.next pb = headA if pb is None else pb.next return pa # only 2 ways to get out of the loop, they meet or the both hit the end=None if __name__ == '__main__': s = Solution() l1 = createList([1, 2, 3, 4, 5]) l2 = createList([8, 3, 4, 5]) assert compareList(s.getIntersectionNode(l1, l2), [3, 4, 5]) == True l1 = createList([1, 3, 5, 7, 9, 11]) l2 = createList([2, 4, 9, 11]) assert compareList(s.getIntersectionNode(l1, l2), [9, 11]) == True l1 = createList([1, 2, 3]) l2 = createList([1, 2]) assert compareList(s.getIntersectionNode(l1, l2), None) == True