代码随想录算法训练营第四天 | 链表part02
24. 两两交换链表中的节点
相邻2个节点进行交换,也设置一个虚拟头节点。
0 -> 1 -> 2
就需要变成
0 -> 2 -> 1
首先第一步需要
0 -> 2,
然后 2 -> 1,
但是1应该指向原先2后面的节点
所以应该首先存储一下1节点以及2节点后面的节点
while(current.next and current.next.next):
temp = current.next # 存储节点1
temp1 = current.next.next.next # 存储2节点后面的节点
current.next = current.next.next # 0 -> 2
current.next.next = temp # 2 —> 1
current.next.next.next = temp1 # 1 -> 2节点后面的节点
current = current.next.next # 让当前节点指向下一次的开头
return dummy_head.next
19.删除链表的倒数第N个节点
思路:快慢指针,快指针先走n+1步,然后和慢指针一起走。
然后走到倒数第N+1个节点的时候,next = next.next
注意:n+1步,是因为删除节点的时候必须走到这个节点的前一个节点。
如果快指针先走n步,那么最后慢指针会指到删除的这个节点,就删不了了。
还有一个更重要的原因,是我们设置了虚拟的头节点。
dummy_head = ListNode(next = head)
fast , slow = dummy_head ,dummy_head
for i in range(n+1):
fast = fast.next
while fast :
fast = fast.next
slow = slow.next
slow.next = slow.next.next
return dummy_head.next
面试题 02.07. 链表相交
注意:数值相同,不代表指针相同。
思路
简单来说,就是求两个链表交点节点的指针。
为了方便举例,假设节点元素数值相等,则节点指针相等。
看如下两个链表,目前curA指向链表A的头结点,curB指向链表B的头结点:
我们求出两个链表的长度,并求出两个链表长度的差值,然后让curA移动到,和curB 末尾对齐的位置,如图:
此时我们就可以比较curA和curB是否相同,如果不相同,同时向后移动curA和curB,如果遇到curA == curB,则找到交点。
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def getIntersectionNode(self, headA, headB):
"""
:type head1, head1: ListNode
:rtype: ListNode
"""
dummy_headA = ListNode(next = headA)
curA = dummy_headA
dummy_headB = ListNode(next = headB)
curB = dummy_headB
countA = 0
countB = 0
while(curA.next):
countA += 1
curA = curA.next
while(curB.next):
countB += 1
curB = curB.next
if countA > countB:
curA = dummy_headA
curB = dummy_headB
cha = countA - countB
for i in range(cha):
curA = curA.next
while(curA != curB):
curA = curA.next
curB = curB.next
if (curA == curB):
return curA
elif countA < countB:
curA = dummy_headA
curB = dummy_headB
cha = countB - countA
for i in range(cha):
curB = curB.next
while(curA != curB):
curA = curA.next
curB = curB.next
if (curA == curB):
return curA
else :
curA = dummy_headA
curB = dummy_headB
while(curA != curB):
curA = curA.next
curB = curB.next
if (curA == curB):
return curA
142.环形链表II
别被题目吓到,其实很简单。
追及问题,A每次跑2步,B每次跑1步,然后在环内相遇,找到相遇的位置。
在相遇之后设置一个index1等于相遇的位置,index2等于head的位置。
然后index1 = index2的时候就是进入环内时的节点,return index1即可
如果没有相遇,那就是无环,return None
dummy_head = ListNode(next = head)
fast = dummy_head.next
slow = dummy_head.next
while fast and fast.next:
fast = fast.next.next
slow = slow.next
if fast == slow :
index1 = fast
index2 = head
while index1 != index2:
index1 = index1.next
index2 = index2.next
return index1
return None
一般涉及到 增删改操作,用虚拟头结点都会方便很多, 如果只能查的话,用不用虚拟头结点都差不多。
当然为了方便记忆,统一都用虚拟头结点。