链表
1、链表的构造
class ListNode:
def __init__(self, val, next = None):
self.val = val
self.next = None
2、移除链表元素
题意: 删除链表中等于给定值val的所有节点
示例1:
输入: head = [1, 2, 3, 4, 5, 6], val = 6
输出: [1, 2, 3, 4, 5]
class Solution:
def remoteNode(self, head, val):
dummy = ListNode(0)
dummy.next = head
pre = dummy
while head:
if head.val == val:
pre.next = head.next
else:
pre = head
head = head.next
return dummy.next
3、设计链表
设计链表的实现。您可以选择使用单链表或双链表。单链表中的节点应该具有两个属性:val
和 next
。val
是当前节点的值,next
是指向下一个节点的指针/引用。如果要使用双向链表,则还需要一个属性 prev
以指示链表中的上一个节点。假设链表中的所有节点都是 0-index 的
在链表类中实现这些功能:
- get(index):获取链表中第 index 个节点的值。如果索引无效,则返回-1。
- addAtHead(val):在链表的第一个元素之前添加一个值为 val 的节点。插入后,新节点将成为链表的第一个节点。
- addAtTail(val):将值为 val 的节点追加到链表的最后一个元素。
- addAtIndex(index,val):在链表中的第 index 个节点之前添加值为 val 的节点。如果 index 等于链表的长度,则该节点将附加到链表的末尾。如果 index 大于链表长度,则不会插入节点。如果index小于0,则在头部插入节点。
- deleteAtIndex(index):如果索引 index 有效,则删除链表中的第 index 个节点。
class ListNode:
def __init__(self, val, next = None):
self.val = val
self.next = next
class MyLinkedList:
def __init__(self):
self.dummy = ListNode(0)
self.count = 0
def get(self, index):
if 0 <= index < self.count:
head = self.dummy.next
while index:
head = head.next
index -= 1
return head.val
else:
return -1
def addAtHead(self, val):
cur = self.dummy
new = ListNode(val)
new.next = cur.next
cur.next = new
self.count += 1
def addAtTail(self, val):
cur = self.dummy
count = self.count
while count:
cur = cur.next
count -= 1
cur.next = ListNode(val)
self.count += 1
def addAtIndex(self, index, val):
if index < 0:
index = 0
elif index > self.count:
return
newnode = ListNode(val)
cur = self.dummy
while index:
cur = cur.next
index -= 1
newnode.next = cur.next
cur.next = newnode
self.count += 1
def deleteAtIndex(self, index):
if 0 <= index < self.count:
cur = self.dummy
while index:
cur = cur.next
index -= 1
cur.next = cur.next.next
self.count -= 1
4、翻转链表
给你单链表的头节点 head
,请你反转链表,并返回反转后的链表。
class Solution:
def reverseList(self, head):
pre = None
cur = head
while cur:
post = cur.next
cur.next = pre
pre = cur
cur = post
return pre
5、两两交换链表中的节点
给你一个链表,两两交换其中相邻的节点,并返回交换后的链表。你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
class ListNode:
def __init__(self, val, next=None):
self.val = val
self.next = next
class Solution:
def swapPairs(self, head):
dummy = ListNode(0)
dummy.next = head
cur = dummy
while cur.next and cur.next.next:
node = cur.next.next.next
post2 = cur.next.next
post1 = cur.next
cur.next = post2
post2.next = post1
post1.next = node
cur = post1
return dummy.next
6、删除链表的倒数第N个节点
19. 删除链表的倒数第 N 个结点 - 力扣(LeetCode)
给你一个链表,删除链表的倒数第n个结点, 并且返回链表的头结点
class ListNode:
def __init__(self, val, next=None):
self.val = val
self.next = next
class Solution:
def removeNthFromEnd(self, head, n):
dummy = ListNode(0)
dummy.next = head
slow, fast = dummy, dummy
while n:
fast = fast.next
n -= 1
while fast.next:
fast = fast.next
slow = slow.next
slow.next = slow.next.next
return dummy.next
7、链表相交
面试题 02.07. 链表相交 - 力扣(LeetCode)
给你两个单链表的头节点 headA
和 headB
,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null
。
图示两个链表在节点 c1
开始相交**:**
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O4E1BOKL-1661650840574)(…/img/image-20220727154254235.png)]
class Solution:
def getIntersectionNode(self, headA, headB):
lenA, lenB = 0, 0
curA, curB = headA, headB
while curA:
lenA += 1
while curB:
lenB += 1
if lenB > lenA:
curA, curB = curB, curA
lenA, lenB = lenA, lenB
n = lenA - lenB
while n:
headA = headA.next
n -= 1
while headA:
if headA == headB:
return headA
headA = headA.next
headB = headB.next
return None
8、环形链表
给定一个链表的头节点 head
,返回链表开始入环的第一个节点。 如果链表无环,则返回 null
。
如果链表中有某个节点,可以通过连续跟踪 next
指针再次到达,则链表中存在环。 为了表示给定链表
中的环,评测系统内部使用整数 pos
来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos
是 -1
,则在该链表中没有环。注意:pos
不作为参数进行传递,仅仅是为了标识链表的实际情况。
不允许修改 链表。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nePqhy1v-1661650840575)(…/img/image-20220727160742716.png)]
两个快慢指针,一个步长为1, 一个步长为2, 如果相遇一定会有环。相遇的位置一定在环内,此时从起点出发一个指针,以相同速度相遇即为环的入口。
class Solution:
def detectCycle(self, head):
slow, fast = head, head
while slow and fast.next and fast.next.next:
slow = slow.next
fast = fast.next.next
if slow == fast:
cur = slow
temp = head
while temp:
if temp == cur:
return temp
temp = temp.next
cur = cur.next
return None
cur = slow
temp = head
while temp:
if temp == cur:
return temp
temp = temp.next
cur = cur.next
return None