代码随想录算法训练营第四天|24. 两两交换链表中的节点、19. 删除链表的倒数第 N 个结点、面试题 02.07. 链表相交、142. 环形链表 II
24. 两两交换链表中的节点
【注意】
1.操作指针一定要指向要反转两个结点的前一个结点
2.遍历链表的时候什么时候终止,cur.next.next == None ,则遍历结束(n为奇数),cur.next == None(n为偶数)。
3.时间复杂度O(n),空间复杂度O(1)
【代码】
1 # Definition for singly-linked list. 2 # class ListNode(object): 3 # def __init__(self, val=0, next=None): 4 # self.val = val 5 # self.next = next 6 class Solution(object): 7 def swapPairs(self, head): 8 """ 9 :type head: ListNode 10 :rtype: ListNode 11 """ 12 dumyhead = ListNode(next = head) 13 cur = dumyhead 14 15 while cur.next and cur.next.next: #顺序不能变,否则会发生空指针异常 16 firstnode = cur.next #临时保存第一个结点 17 thirdnode = cur.next.next.next #临时保存第三个结点 18 cur.next = cur.next.next #步骤1 19 cur.next.next = firstnode #步骤2 20 firstnode.next = thirdnode #步骤3 21 cur = cur.next.next 22 23 return dumyhead.next
19. 删除链表的倒数第 N 个结点
【代码】双指针
1 # Definition for singly-linked list. 2 # class ListNode(object): 3 # def __init__(self, val=0, next=None): 4 # self.val = val 5 # self.next = next 6 class Solution(object): 7 def removeNthFromEnd(self, head, n): 8 """ 9 :type head: ListNode 10 :type n: int 11 :rtype: ListNode 12 """ 13 dumyhead = ListNode(next = head) 14 fast = dumyhead 15 slow = dumyhead 16 #n += 1 #防止fast为空,发生空指针异常 #快指针走n+1步 17 while n >= 0 and fast: 18 fast = fast.next 19 n -= 1 20 while fast: 21 slow = slow.next 22 fast = fast.next #慢指针才能到要操作结点的前一个结点 23 slow.next = slow.next.next #遍历结束之后删除 24 25 return dumyhead.next
面试题 02.07. 链表相交
【注意】
1.交点不是数值相等,而是指针相等。
【代码】
1 # Definition for singly-linked list. 2 # class ListNode(object): 3 # def __init__(self, x): 4 # self.val = x 5 # self.next = None 6 7 class Solution(object): 8 def getIntersectionNode(self, headA, headB): 9 """ 10 :type head1, head1: ListNode 11 :rtype: ListNode 12 """ 13 lenA, lenB = 0, 0 14 cur = headA 15 16 while cur: #求链表A长度 17 cur = cur.next 18 lenA += 1 19 20 cur = headB 21 while cur: #求链表B长度 22 cur = cur.next 23 lenB += 1 24 25 curA, curB = headA, headB 26 if lenA > lenB: # 让curB为最长链表的头,lenB为其长度 27 curA, curB = curB, curA 28 lenA, lenB = lenB, lenA 29 30 for _ in range(lenB - lenA): # 让curA和curB在同一起点上(末尾位置对齐) 31 curB = curB.next 32 33 while curA: 34 if curA == curB: 35 return curA 36 else: 37 curA = curA.next 38 curB = curB.next 39 return None
142. 环形链表 II
【注意】
1.双指针判断有没有环,从头结点出发,fast指针每次移动两个节点,slow指针每次移动一个节点,
2.其实相对于slow来说,fast是一个节点一个节点的靠近slow的
3.如果有环,如何找到这个环的入口
【代码】
1 # Definition for singly-linked list. 2 # class ListNode(object): 3 # def __init__(self, x): 4 # self.val = x 5 # self.next = None 6 7 class Solution(object): 8 def detectCycle(self, head): 9 """ 10 :type head: ListNode 11 :rtype: ListNode 12 """ 13 slow, fast = head, head 14 while fast and fast.next: #只需要判断fast不为None 15 slow = slow.next 16 fast = fast.next.next 17 #相遇 18 if fast == slow: #寻找环的入口 19 index1 = fast 20 index2 = head 21 while index1 != index2: 22 index1 = index1.next 23 index2 = index2.next 24 return index1 25 return None #无环