本文介绍 LeetCode 题集中,有关链表的问题。
LeetCode 其他有关链表的问题:
LeetCode 题集:链表(一)
LeetCode 题集:链表(二)
19. Remove Nth Node From End of List(删除链表的倒数第 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:
dummy = ListNode(val=-1, next=head)
num_node = 0 # number of nodes
while head:
num_node += 1
head = head.next
res = dummy
head = dummy
while head.next:
if num_node == n:
head.next = head.next.next
break
else:
num_node -= 1
head = head.next
res = res.next
return res
运行效果:
其二,快慢指针法, 先将快指针移动 N 步,然后快慢指针同时移动,当快指针移动到结尾时,慢指针即处在倒数第 N+1 个节点,将其 next 指向倒数第 N-1 个节点(下下个节点)即可。
代码如下:
# 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:
fast, slow = head, head
# move fast n steps in advance
for i in range(n):
fast = fast.next
# special case: remove the 1st node
if not fast:
return head.next
# move fast and slow together
while fast.next:
fast = fast.next
slow = slow.next
slow.next = slow.next.next # remove the nth node from the end
return head
运行效果:
203. Remove Linked List Elements(移除链表元素)
问题描述
思路与代码
本题思路简单,逐个节点遍历,对于需要删除的节点,修改其前一个节点的 next 参数即可。
代码如下:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def removeElements(self, head: ListNode, val: int) -> ListNode:
dummy = ListNode(val=-1, next=head)
head = dummy
while head.next:
if head.next.val == val:
head.next = head.next.next
else:
head = head.next
res = dummy.next
return res
运行效果:
61. Rotate List(旋转链表)
问题描述
思路与代码
本题的思路,观察链表旋转的结果,可以看出旋转相当于将链表切为两段再重新拼接起来。可以通过旋转次数 k 来确定切割的位置,然后修改对应节点的 next 参数即可。
注意两种特殊情况:
- 链表为空时,直接返回原空链表
- 将旋转次数 k 对链表长度求余,若结果为 0,则返回原链表
代码如下:
# 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: Optional[ListNode], k: int) -> Optional[ListNode]:
if not head:
return head
dummy = ListNode(val=-1, next=head)
num_node = 0
head = dummy
while head.next:
num_node += 1
head = head.next
# in case: k > num_node
k %= num_node
if not k:
return dummy.next
head_ori = dummy.next # original head
head = dummy.next
for _ in range(num_node - k):
head = head.next
dummy.next = head # new head
for _ in range(k - 1):
head = head.next
head.next = head_ori # next node of tail -> original head
for _ in range(num_node - k):
head = head.next
head.next = None
return dummy.next
运行效果:
官方题解给出了另一种思路,先将链表成环,然后根据旋转次数 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 not head or not head.next:
return head
n = 1 # number of nodes
cur = head
while cur.next:
cur = cur.next
n += 1
k %= n # k < n
if not k:
return head
cur.next = head
for _ in range(n - k):
cur = cur.next
res = cur.next
cur.next = None # break the loop
return res
运行效果: