Leetcode 单链表题型总结
自己刷题的一个小记录,难度从easy --> hard,持续更新中。若有更好的方法,欢迎评论区讨论呀。
876. 返回单链表的中间节点。如果有两个中间节点,返回第二个。
两种思路,
第一种是先遍历一遍,记录长度后,再遍历到一半。时间复杂度O(n)
第二种是用两个指针,一快一慢,快指针每次走两步,慢指针每次走一步,当快指针走到链表最后时,慢指针所指的就是中间节点。
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
'''
先遍历一遍,记录长度,再遍历一半。
class Solution:
def middleNode(self, head: ListNode) -> ListNode:
if head.next ==None:
return head
length = 1
phead = head
while head.next !=None:
length +=1
head = head.next
mid = length//2
for i in range(mid):
phead = phead.next
return phead
'''
# 直接快慢指针,快的到头以后,慢的就是中间值
class Solution:
def middleNode(self, head: ListNode) -> ListNode:
if head.next ==None:
return head
fast = head
slow = head
while fast and fast.next:
fast = fast.next.next
slow = slow.next
return slow
206. 反转单链表
两种思路
递归
迭代
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
'''
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
# 递归版本,一直往后遍历,每次建立一个反转链接
return self.reverse(head,None)
def reverse(self, current, prev):
if current == None:
return prev
nxt = current.next
current.next = prev
prev = current
current = nxt
return self.reverse(current, prev)
'''
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
# 迭代版本
return self.reverse(head,None)
def reverse(self, current, prev):
if current == None:
return prev
while current!=None:
nxt = current.next
current.next = prev
prev = current
current = nxt
return prev
237. 删除单链表中的某一节点
这题要注意的是,并没有给出完整的链表,函数参数中只是给了要删除的节点。
但由于是单链表,没法获取被删除节点前的节点,所以将被删除节点的值改为后面一个节点的值,然后删除后面一个节点即可。
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def deleteNode(self, node):
"""
:type node: ListNode
:rtype: void Do not return anything, modify node in-place instead.
"""
# 没有给完整的单链表,只是给了要删除的节点!没有head!
node.val = node.next.val
node.next = node.next.next
21. 合并两个已排序的单链表
用两个指针分别遍历两个链表。遇到较小的一个,就加到合并列表后面,并指针后移。
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
newlist = ListNode(0)
tmp = newlist
while l1!=None and l2!=None:
if l1.val<l2.val:
tmp.next = l1
l1 = l1.next
else:
tmp.next = l2
l2 = l2.next
tmp = tmp.next
if l1!=None:
while l1!=None:
tmp.next = l1
l1 = l1.next
tmp = tmp.next
if l2!=None:
while l2!=None:
tmp.next = l2
l2 = l2.next
tmp = tmp.next
return newlist.next
83.给定一个排序后的单链表,删除其中的重复节点,保证每个节点只出现一次。
思路:遇到重复的节点,就往后遍历,直到节点不重复即可。
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def deleteDuplicates(self, head: ListNode) -> ListNode:
tmp = head
while tmp!=None:
nxt = tmp.next
while nxt!=None and nxt.val== tmp.val:
nxt = nxt.next
tmp.next = nxt
tmp = nxt
return head
141. 判断单链表是否有环
思路:用快慢指针,如果有环,那么两个指针一定会相遇。
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def hasCycle(self, head):
"""
:type head: ListNode
:rtype: boo