dummy = ListNode(-1) cur = dummy # 面说到了,我们定义了dummy后,还需要定义一个cur指向他,对他的值进行修改,然后cur动dummy不动 for i in res[::-1]: cur.next = ListNode(i) cur = cur.next return dummy.next
注意,千万不能写成如下的形式
1 2 3 4 5
dummy = ListNode(-1) for i in res[::-1]: dummy.next = ListNode(i) dummy = dummy.next return dummy.next
这里用到dummy指针就有用了
将链表从中间断开
目的是为了二分,便于后面进行归并排序,下面这段代码集中了错误和正确的,可以对比下
1 2 3 4 5 6 7 8 9
# 错误的 slow = cur fast = cur while fast and fast.next: slow = slow.next fast = fast.next.next right = slow.next slow.next = None left_sort_results = merge_sort(cur)
这样在递归的时候,程序会无限,无法跳出,下面看下没问题的结果
1 2 3 4 5 6 7 8 9
slow = cur fast = cur pre = None while fast and fast.next: pre = slow slow = slow.next fast = fast.next.next pre.next = None left_sort_results = merge_sort(cur)
# 1. 建议写法 slow = head fast = head while fast and fast.next: slow = slow.next fast = fast.next.next # 2. 不建议写法 slow = head fast = head.next while fast and fast.next: slow = slow.next fast = fast.next.next
# Definition for singly-linked list. # class ListNode: # def __init__(self, val=0, next=None): # self.val = val # self.next = next classSolution: defreverseBetween(self, head, left, right): dummy = ListNode(-1, next=head) first = dummy for i inrange(left-1): first = first.next first_above = first first = first.next
second = dummy for j inrange(right): second = second.next second_after = second.next
cur = first second.next = None
defreversePart(head): pre = None cur = head while cur: next = cur.next cur.next = pre pre = cur cur = next return pre, head reverse_head, reverse_tail = reversePart(cur) first_above.next = reverse_head reverse_tail.next = second_after return dummy.next
classSolution: defreverseKGroup(self, head, k): # 旋转链表 defreversePart(head): pre = None cur = head while cur: next = cur.next cur.next = pre pre = cur cur = next return pre, head # 统计节点数量 node1 = head cnt = 0 while node1: cnt += 1 node1 = node1.next # 保存每段的链表反转后的开始点和结束点 res = [] cur = head old_cur = head for i inrange(cnt // k): # 这里不要考虑最后一段哈,最后一段在res.append([cur, cur])这里 for j inrange(k - 1): cur = cur.next tail_old = cur.next cur.next = None new_head, new_tail = reversePart(old_cur) res.append([new_head, new_tail]) cur = tail_old old_cur = tail_old res.append([cur, cur]) for i inrange(len(res) - 1): res[i][1].next = res[i + 1][0] return res[0][0]
classSolution: defsortList(self, head: ListNode) -> ListNode: defmerge(p1, p2): dummy = ListNode(-1) cur = dummy while p1 and p2: if p1.val < p2.val: cur.next = p1 p1 = p1.next else: cur.next = p2 p2 = p2.next cur = cur.next cur.next = p1 if p1 else p2 return dummy.next
defmerge_sort(cur): ifnot cur ornot cur.next: return cur slow = cur fast = cur pre = None while fast and fast.next: # 这里要注意为啥要用pre这个东西,如果不要,直接将slow.next作为后半段,然后将cur作为前半段的话,会出问题 pre = slow slow = slow.next fast = fast.next.next pre.next = None left_sort_results = merge_sort(cur) right_sort_results = merge_sort(slow) return merge(left_sort_results, right_sort_results) return merge_sort(head)
classSolution: defreorderList(self, head: Optional[ListNode]) -> None: """ Do not return anything, modify head in-place instead. """ from collections import deque cur = head node_list = [] while cur: node_list.append(cur) cur = cur.next queue = deque([]) for i in node_list[::-1]: i.next = None queue.insert(0, i)
dummy = ListNode(-1) cur = dummy while queue: if queue: cur.next = queue.popleft() cur = cur.next if queue: cur.next = queue.pop() cur = cur.next return dummy.next
classSolution: defdeleteDuplicates(self, head: Optional[ListNode]) -> Optional[ListNode]: left = dummy = ListNode(-9999,next=head) right = head # 最好别right=dummy,和后面那道题保持一致 while right: if right.val == left.val: right = right.next continue left.next = right left = left.next right = right.next left.next = None return dummy.next
和之前的删除数组元素中的重复值很像,代码如下:
1 2 3 4 5 6 7 8 9 10
classSolution: defremoveDuplicates(self, nums: List[int]) -> int: left = 0 for right inrange(1, len(nums)): pass#这里不需要操作啥 if nums[right] == nums[left]: continue left = left + 1 nums[left] = nums[right] return left + 1
classSolution: defdeleteDuplicates(self, head: Optional[ListNode]) -> Optional[ListNode]: cur = head values = set() duplicated_values = set() while cur: val = cur.val if val in values: duplicated_values.add(val) values.add(val) cur = cur.next left = dummy = ListNode(-9999,next=head) right = head # 最好别right=dummy,和后面那道题保持一致 while right: if right.val in duplicated_values: right = right.next continue left.next = right left = left.next right = right.next left.next = None return dummy.next
classSolution: defremoveElements(self, head: Optional[ListNode], val: int) -> Optional[ListNode]: ifnot head: return head left = dummy = ListNode(-1, next=head) right = head # 不能right=dummy,不然会一直while while right: if right.val == val: right = right.next continue left.next = right left = left.next# 这两段代码不要顺序弄错了 right = right.next left.next = None return dummy.next
最好用一个dummy来做,这样方便操作。和数组中的删除一个元素很像,那道题的代码如下:
1 2 3 4 5 6 7 8 9 10
classSolution: defremoveElement(self, nums: List[int], val: int) -> int: left = 0 for right inrange(len(nums)): pass#这里不需要操作啥 if nums[right] == val: continue nums[left] = nums[right] left = left + 1 return left
# 首位相连构成环 head1.next = headB # 快慢指针 slow = headA fast = headA while fast and fast.next: slow = slow.next# 这里容易弄错,把判断写在前面了 fast = fast.next.next if slow == fast: p = headA q = slow while p != q: p = p.next q = q.next head1.next = None head2.next = None return p
head1.next = None head2.next = None returnNone
更简单的代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13
# Definition for singly-linked list. # class ListNode: # def __init__(self, x): # self.val = x # self.next = None
classSolution: defgetIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode: A, B = headA, headB while A != B: #这里写错成A and B A = A.nextif A else headB B = B.nextif B else headA return A
# Definition for singly-linked list. # class ListNode: # def __init__(self, x): # self.val = x # self.next = None
classSolution: defhasCycle(self, head: Optional[ListNode]) -> bool: ifnot head ornot head.next: returnFalse slow = head fast = head # 这里也可以head.next while fast and fast.next: slow = slow.next fast = fast.next.next# 别写错了 if slow == fast: returnTrue returnFalse
# Definition for singly-linked list. # class ListNode: # def __init__(self, x): # self.val = x # self.next = None
classSolution: defdetectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]: slow = head fast = head while fast and fast.next: slow = slow.next fast = fast.next.next if slow == fast: # 注意:下面的操作不熟悉 p = slow q = head while p!=q: p= p.next q=q.next return p returnNone
classSolution: defsplitListToParts(self, head: Optional[ListNode], k: int) -> List[Optional[ListNode]]: cur = head cnt = 0 while cur: cnt = cnt + 1 cur = cur.next a, b = divmod(cnt, k) res = [a for i inrange(k)] for i inrange(b): res[i] = res[i] + 1 new_res = [] cur = head for lens in res: if lens==0: new_res.append(None) continue else: new_res.append(cur) for i inrange(lens-1): #注意点1 cur = cur.next new_head = cur.next cur.next = None# 注意点2 cur = new_head return new_res
# Definition for singly-linked list. # class ListNode: # def __init__(self, val=0, next=None): # self.val = val # self.next = next classSolution: defpartition(self, head: Optional[ListNode], x: int) -> Optional[ListNode]: small_dummy = ListNode(-1) big_dummy = ListNode(-2)
small = small_dummy big = big_dummy
cur = head while cur: if cur.val < x: small.next = cur small = small.next else: big.next = cur big = big.next cur = cur.next big.next = None small.next = big_dummy.next return small_dummy.next
上述我在写的时候没有注意,直接用如下代码,导致了错误
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
classSolution: defpartition(self, head: Optional[ListNode], x: int) -> Optional[ListNode]: small = ListNode(-1) big = ListNode(-2) cur = head while cur: if cur.val < x: small.next = cur small = small.next else: big.next = cur big = big.next cur = cur.next big.next = None small.next = big.next return small.next
# Definition for singly-linked list. # class ListNode: # def __init__(self, val=0, next=None): # self.val = val # self.next = next classSolution: deftrainingPlan(self, head: Optional[ListNode], cnt: int) -> Optional[ListNode]: lens = 0 cur = head while cur: lens += 1 cur = cur.next p = head for i inrange(lens-cnt): p = p.next return p
# Definition for singly-linked list. # class ListNode: # def __init__(self, val=0, next=None): # self.val = val # self.next = next classSolution: defmiddleNode(self, head: ListNode) -> ListNode: if head.next == None: return head cur = head allNodes = [] while cur.next: allNodes.append(cur) cur = cur.next allNodes.append(cur) return allNodes[int(len(allNodes)//2)]
# Definition for singly-linked list. # class ListNode: # def __init__(self, val=0, next=None): # self.val = val # self.next = next classSolution: defoddEvenList(self, head: Optional[ListNode]) -> Optional[ListNode]: ifnot head: return head ifnot head.next: return head A = head B = head.next
first = A second = B
while second and second.next: temp1 = first.next.next first.next = first.next.next first = temp1
temp2 = second.next.next second.next = second.next.next second = temp2
# Definition for singly-linked list. # class ListNode: # def __init__(self, val=0, next=None): # self.val = val # self.next = next classSolution: defoddEvenList(self, head: Optional[ListNode]) -> Optional[ListNode]: ifnot head: return head ifnot head.next: return head A = head B = head.next
first = A second = B # 下面这么写的话自己画画图就知道一旦使用fast.next后,链表原来的顺序结构就被打断了,再去寻的话就会出错。 while first and first.next: temp1 = first.next.next first.next = first.next.next first = temp1
while second and second.next: temp2 = second.next.next second.next = second.next.next second = temp2
# Definition for singly-linked list. # class ListNode: # def __init__(self, val=0, next=None): # self.val = val # self.next = next classSolution: defaddTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]: defget_list(head): cur = head res = [] while cur: res.append(cur.val) cur = cur.next return res l1_res = get_list(l1) l2_res = get_list(l2)
max_lens = max(len(l1_res), len(l2_res)) res = [] a = 0 for i inrange(max_lens): n1 = l1_res[i] if i<len(l1_res) else0 n2 = l2_res[i] if i<len(l2_res) else0 a, b = divmod(n1+n2+a, 10) res.append(b) if a>0: res.append(a) dummy = ListNode(-1) #说到了,我们定义了dummy后,还需要定义一个cur指向他,对他的值进行修改,然后cur动dummy不动 cur = dummy for i in res: cur.next = ListNode(i) cur = cur.next return dummy.next
# Definition for singly-linked list. # class ListNode: # def __init__(self, val=0, next=None): # self.val = val # self.next = next classSolution: defaddTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]: # 获取链表的值 defget_list(head): cur = head res = [] while cur: res.append(cur.val) cur = cur.next return res l1_res = get_list(l1)[::-1] l2_res = get_list(l2)[::-1]
# 获取最大的长度 max_lens = max(len(l1_res), len(l2_res)) res = [] a = 0 for i inrange(max_lens): n1 = l1_res[i] if i<len(l1_res) else0 n2 = l2_res[i] if i<len(l2_res) else0 a, b = divmod(n1+n2+a, 10) res.append(b) if a>0: res.append(a) dummy = ListNode(-1) # 说到了,我们定义了dummy后,还需要定义一个cur指向他,对他的值进行修改,然后cur动dummy不动 cur = dummy for i in res[::-1]: cur.next = ListNode(i) cur = cur.next return dummy.next