文档:programmercarl.com
今天的题算是链表的扩充题吧,学完感觉双指针真好用(就是自己想不出来),难度的话,我觉得24和142比较难,其他还好,甚至能暴力解
24.两两交换链表中的节点
这一题是我今天写过最难的题,直接当头一棒,以至于我现在还有点懵逼
直接放代码吧,我肯定讲不明白
class Solution(object):
def swapPairs(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
vir_head = ListNode(next = head)
cur = vir_head
while cur.next and cur.next.next:
temp = cur.next # 记录的是1号节点
temp1 = cur.next.next.next # 记录的是3号节点
cur.next = cur.next.next # vir节点next指向2节点
cur.next.next = temp #2号节点指向1节点
temp.next = temp1 # 1号节点指向3号节点
cur = cur.next.next # cur指针移动到1号节点
return vir_head.next
19.删除链表中的倒数第n个节点
这道倒是第一次就AC了,我刚开始没有用双指针,而是用的暴力解,就是先遍历找出链表的长度,然后用长度-n就可以算出要删除第几个节点了,再遍历到对应的位置删除就行
class Solution(object):
def removeNthFromEnd(self, head, n):
vir_head = ListNode(next = head)
cur = vir_head
len = 0 # 计数器
while cur.next != None: # 遍历得出链表的长度
cur = cur.next
len += 1
cur = vir_head
for i in range(len - n): # 遍历第二次到倒数n的位置处
cur = cur.next
cur.next = cur.next.next # 删除节点
return vir_head.next # 返回结果
还有一种就是双指针写法了,先让fast指针走到前面去,正好和slow指针形成一个差值n,然后二者同时向前走,当fast指针走到结尾时,说明slow指针走到了倒数第n位
class Solution_answer(object):
def removeNthFromEnd(self, head, n):
vir_head = ListNode(next = head)
slow = vir_head #定义慢指针
fast = vir_head #定义快指针
for i in range(n + 1): #快指针先遍历到目标位置
fast = fast.next
while fast != None: #快慢指针一起走,直到快指针走到终点
slow = slow.next
fast = fast.next
slow.next = slow.next.next #删除节点
return vir_head.next
160.相交链表
这道题我没有思路,但是一看答案代码就明白了,不难,原来遍历求长度也不是不行
首先计算出每个链表的长度,然后长链表减去差值后,就和短链表的起始位置一样了,然后二者开始同时遍历,直到碰见相同的节点,这个节点就是相交节点了
class Solution(object):
def getIntersectionNode(self, headA, headB):
lenA = 0
lenB = 0
cur = headA
while cur:
cur = cur.next
lenA += 1
cur = headB
while cur:
cur = cur.next
lenB += 1
curA = headA
curB = headB
if lenA > lenB: # 让curB为最长链表的头
curA, curB = curB, curA
lenA, lenB = lenB, lenA
for _ in range(lenB - lenA): # 让curB指针移动到和curA同一位置
curB = curB.next
while curA:
if curA == curB:
return curA
else:
curA = curA.next
curB = curB.next
return None # 没有相同的节点,就返回None
142.环形链表
这个题吧,emmmm,还是得看数学功底,我数学不好,讲不明白,但是看着那张动图还是能写出来代码的
"""
数学问题,麻了,果然算法就是灵活的,双指针是真的猛啊
"""
class Solution(object):
def detectCycle(self, head):
# 首先判断是否有环
fast = head
slow = head
indexA, indexB = head, None # 找出环的入口
while fast and fast.next:
fast = fast.next.next
slow = slow.next
if fast == slow: # 找到两个指针相遇的节点
indexB = slow
while indexA != indexB: # 当indexA和indexB相遇的时候,说明该节点就是环入口
indexA = indexA.next
indexB = indexB.next
return indexA
return None
(动图可以去网站找,这里就不粘贴了)
等后天考完试就可以好好写算法了,呜呜