链表是一种重要的数据结构,在算法和数据结构的学习和实践中扮演着重要的角色。本篇技术博客将结合LeetCode上的几个典型问题,介绍如何使用链表来解决这些问题,并帮助读者更好地掌握链表的基础知识与应用。
LeetCode题目
题目1:删除链表中的节点
题目描述:给定一个单链表中的一个节点,删除该节点,不给定链表的头节点。
示例:
输入: node = 5
输出: [4,1,9]
解释: 给定链表为 4->5->1->9,删除节点 5 后,链表变为 4->1->9。
解题思路:由于只给定了要删除的节点,而没有给出链表的头节点,因此需要先将该节点的下一个节点的值复制到该节点,然后删除该节点的下一个节点。
代码实现:
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
题目2:两数相加
题目描述:给定两个非空的链表,表示两个非负整数。数字以相反的顺序存储,每个节点包含一个数字。求这两个数的和,并将其以相反的顺序输出。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
解题思路:由于链表中的数字是以相反的顺序存储的,因此需要先将链表中的数字反转,然后再将它们相加,最后再将结果反转回来。
代码实现:
class Solution:
def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
def reverseList(head):
prev = None
curr = head
while curr:
next_node = curr.next
curr.next = prev
prev = curr
curr = next_node
return prev
def addList(l1, l2):
carry = 0
dummy = ListNode(0)
curr = dummy
while l1 or l2 or carry:
val1 = l1.val if l1 else 0
val2 = l2.val if l2 else 0
sum_val = val1 + val2 + carry
carry = sum_val // 10
curr.next = ListNode(sum_val % 10)
curr = curr.next
l1 = l1.next if l1 else None
l2 = l2.next if l2 else None
return dummy.next
l1 = reverseList(l1)
l2 = reverseList(l2)
result = addList(l1, l2)
return reverseList(result)
题目3:环形链表
题目描述:给定一个链表,判断链表中是否有环。
示例:
输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。
解题思路:使用快慢指针的方法,快指针每次移动两步,慢指针每次移动一步,如果快指针追上了慢指针,说明有环。
代码实现:
class Solution:
def hasCycle(self, head: ListNode) -> bool:
fast = head
slow = head
while fast and fast.next:
fast = fast.next.next
slow = slow.next
if fast == slow:
return True
return False
题目4:删除链表的倒数第N个节点
题目描述:给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头节点。
示例:
输入:[1,2,34,5], n = 2
输出:[1,2,3,5]
解释:删除倒数第二个节点后,链表变为 1->2->3->5。
解题思路:使用快慢指针的方法,先让快指针移动n步,然后让快指针和慢指针同时移动,当快指针到达链表末尾时,慢指针指向的节点就是要删除的节点。
代码实现:
class Solution:
def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
dummy = ListNode(0)
dummy.next = head
fast = slow = dummy
for i in range(n):
fast = fast.next
while fast.next:
fast = fast.next
slow = slow.next
slow.next = slow.next.next
return dummy.next
总结
本篇技术博客介绍了链表结构在LeetCode上的几个典型问题,并提供了相应的解题思路和代码实现。通过这些例子,读者可以更好地掌握链表的基础知识和应用,同时也能够提高自己的算法和数据结构能力。当然,链表还有很多其他的应用场景和问题,读者可以通过继续学习和实践来进一步深入了解。