通过实践Leetcode题目掌握链表结构

83 阅读3分钟

链表是一种重要的数据结构,在算法和数据结构的学习和实践中扮演着重要的角色。本篇技术博客将结合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上的几个典型问题,并提供了相应的解题思路和代码实现。通过这些例子,读者可以更好地掌握链表的基础知识和应用,同时也能够提高自己的算法和数据结构能力。当然,链表还有很多其他的应用场景和问题,读者可以通过继续学习和实践来进一步深入了解。