顺序参考:https://leetcode-cn.com/circle/article/48kq9d/
四、链表
题目分类 | 题目编号 |
---|---|
链表的删除 | |
链表的遍历 | |
链表的旋转与反转 | |
链表高精度加法 | |
链表的合并 |
203. 移除链表元素
给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。
class Solution:
def removeElements(self, head: ListNode, val: int) -> ListNode:
#用ret记录答案链表的开头,tmp用来制作链表,最后返回ret
tmp = ret = ListNode()
while head:
if head.val != val:
tmp.next = head
tmp = tmp.next
head = head.next
tmp.next = None
return ret.next
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.
"""
node.val = node.next.val
node.next = node.next.next
19. 删除链表的倒数第 N 个结点
给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
思路:设两个指针,中间相差n,后面的指针到最后一个元素时,前面的指针正好指到改删除的元素的前一个
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
left = right = head
count = 0
while count < n:
right = right.next
count += 1
if not right:
return head.next
while right.next:
left = left.next
right = right.next
if left.next:
left.next = left.next.next
return head
430. 扁平化多级双向链表
"""
# Definition for a Node.
class Node:
def __init__(self, val, prev, next, child):
self.val = val
self.prev = prev
self.next = next
self.child = child
"""
class Solution:
def flatten(self, head: 'Node') -> 'Node':
cur = head
tmp = None
while cur:
if cur.child:#如果需要铺平
tmp = cur.next#记录有孩子节点的下一个节点
p = self.flatten(cur.child)#展平
cur.next = p #将当前节点指向铺平的链表
p.prev = cur #铺平链表和之前链表连起来
cur.child = None
q = cur #连起来之后找到铺平列表的尾部
while q.next:
q = q.next
q.next = tmp#找到后与原节点的下一个节点连起来
if tmp is not None: tmp.prev = q#如果没下一个节点就不用连prev了
cur = tmp
else:#不需要铺平直接下一个
cur = cur.next
return head
61. 旋转链表
给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置。
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def rotateRight(self, head: ListNode, k: int) -> ListNode:
if head == None or k == 0:return head
l = 1
cur = head
while cur.next is not None:#计算节点个数
cur = cur.next
l += 1
cur.next = head#顺便连成个环
count = l - k%l#计算移动几个
if count == 0:#不移动把环断掉
cur.next = None
return head
for i in range(count):#移动
cur = cur.next
ans = cur.next
cur.next = None#移动到地方了断环
return ans
24. 两两交换链表中的节点
给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
思路:用栈构造一个新列表
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def swapPairs(self, head: ListNode) -> ListNode:
if not (head and head.next):
return head
p = ListNode(-1)#构造一个新的链表
cur,head,stack = head,p,[]#答案返回head.next
while cur and cur.next:
stack.append(cur)
stack.append(cur.next)
cur = cur.next.next
p.next = stack.pop()
p.next.next = stack.pop()
p = p.next.next
#原链表长度为奇数时最后还剩下一个数
if cur:
p.next = cur
else:
p.next = None
return head.next
206. 反转链表
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
思路:两个指针,一前一后直接翻转(改变next的指向方向),需要中间变量做存储
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
if not(head and head.next):return head
cur = head.next
pre = head
pre.next = None
while cur:
tmp = cur.next
cur.next = pre
pre = cur
cur = tmp
return pre
92. 反转链表 II
给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。
指向 left 左边元素的指针 pre ,它表示未翻转的链表,需要把当前要翻转的链表结点放到 pre 之后。
cur 指向当前要翻转的链表结点。
nxt 指向 cur.next ,表示下一个要被翻转的链表结点。
tail 指向已经翻转的链表的结尾,用它来把已翻转的链表和剩余链表进行拼接。
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution(object):
def reverseBetween(self, head, left, right):
count = 1
dummy = ListNode(