文章目录
24. Swap Nodes in Pairs
Given a linked list, swap every two adjacent nodes and return its head. You must solve the problem without modifying the values in the list’s nodes (i.e., only nodes themselves may be changed.)
Input: head = [1,2,3,4]
Output: [2,1,4,3]
Sol:
class Solution:
def swapPairs(self, head: Optional[ListNode]) -> Optional[ListNode]:
dummy_head = ListNode(next=head)
current = dummy_head
while current.next and current.next.next:
# save temp variables
first = current.next
second = current.next.next
third = current.next.next.next
# need in, between, and out pointers change
current.next = second # step1: 0->2
second.next = first # step2: 2->1
first.next = third # step3: 1->3
current = current.next.next
return dummy_head.next
-
Note:
- save temp variables
- need 3 steps for in, between, and out pointers change
- Dummy head: 链表题看似是操作结点,其实是操作节点间的箭头,dummy head使头结点也有in and out箭头,否则头结点需要单独处理,因为没有In箭头
========================================
19. Remove Nth Node From End of List
Given the head of a linked list, remove the nth node from the end of the list and return its head. (倒数第n个结点)
Input: head = [1,2,3,4,5], n = 2
Output: [1,2,3,5]
class Solution:
def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
dummy_head = ListNode(next=head)
p_s,p_f=dummy_head,dummy_head
for i in range(n): # fast move n steps first
p_f=p_f.next
while p_f.next: # ".next:" slow will be at the prior node pointing to the delete node
p_s=p_s.next
p_f=p_f.next
p_s.next = p_s.next.next
return dummy_head.next
- Notes:
- Two pointers, fast first move n, then when fast get end, slow is at end n.
- make slow pointer stop at prior node pointing to the delete node, so “while fast.next” rather than “while fast”
- O(n),O(1)
========================================
160. Intersection of Two Linked Lists
Given the heads of two singly linked-lists headA and headB, return the node at which the two lists intersect. If the two linked lists have no intersection at all, return null.
Input: intersectVal = 8, listA = [4,1,8,4,5], listB = [5,6,1,8,4,5], skipA = 2, skipB = 3
Output: Intersected at ‘8’
Sol:
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> Optional[ListNode]:
cur_a=headA
cur_b=headB
while cur_a != cur_b:
if cur_a==None and cur_b==None:
return None
cur_a = cur_a.next if cur_a else headB
cur_b = cur_b.next if cur_b else headA
return cur_a
- Note: 一个List遍历到尾,从另一个头继续,两个碰到时就是intersection
- O(n), O(1)
========================================
142. Linked List Cycle II
Given the head of a linked list, return the node where the cycle begins. If there is no cycle, return null.
T here is a cycle in a linked list if there is some node in the list that can be reached again by continuously following the next pointer. Internally, pos is used to denote the index of the node that tail’s next pointer is connected to (0-indexed). It is -1 if there is no cycle. Note that pos is not passed as a parameter.
Do not modify the linked list.
Input: head = [3,2,0,-4], pos = 1
Output: tail connects to node index 1
Explanation: There is a cycle in the linked list, where tail connects to the second node.
Sol
class Solution:
def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]:
if not head or not head.next:
return None
fast,slow,ptr=head,head,head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if fast == slow:
while ptr != slow:
ptr = ptr.next
slow = slow.next
return ptr
return None
- Notes:
-
- find loop: fast go 2 steps, slow go 1 step, until meet
-
- find loop enter: new pointer “ptr” starts from head, “slow” starts from when fast and slow meets. Then when ptr and slow meets while each move 1 step forward, it is the enter.
-
- “ptr” can be replaced by re-use and re-init “fast” pointer.
-