返回

链表练习 Day3&4:掌握链表基本操作,夯实算法基础

闲谈

链表的本质:理解指针的移动

链表是一种动态数据结构,它由一个个节点组成,每个节点包含数据和指向下一个节点的指针。链表的精髓在于指针的移动,通过改变指针指向,我们可以遍历、插入和删除链表中的数据。

指针移动的常见场景

遍历链表

while (curr != null) {
    // 对当前节点进行操作
    curr = curr.next;
}

插入节点

// 创建一个新节点
Node newNode = new Node(data);

// 将新节点插入到 curr 节点之后
newNode.next = curr.next;
curr.next = newNode;

删除节点

// 将要删除的节点
Node toDelete = curr.next;

// 将 toDelete 节点从链表中移除
curr.next = toDelete.next;

练习是关键:LeetCode 实战

LeetCode 提供了许多链表练习题,它们涵盖了链表操作的各个方面。通过这些练习,您可以加深对链表的理解,提高您的算法解决能力。

Day3:两数相加

题目 给定两个非负整数链表,代表两个非负整数。将它们相加并返回一个新的链表。

图示示例:

两数相加示意图

代码示例:

public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
    // 初始化进位和虚拟头结点
    int carry = 0;
    ListNode dummy = new ListNode(0);
    ListNode curr = dummy;

    // 遍历两个链表,直到两个链表都为空
    while (l1 != null || l2 != null) {
        // 获取两个链表当前节点的值,加上进位
        int sum = (l1 != null ? l1.val : 0) + (l2 != null ? l2.val : 0) + carry;

        // 更新进位和当前节点的值
        carry = sum / 10;
        curr.next = new ListNode(sum % 10);

        // 移动两个链表的指针和当前节点指针
        l1 = l1 != null ? l1.next : l1;
        l2 = l2 != null ? l2.next : l2;
        curr = curr.next;
    }

    // 如果进位不为 0,则添加进位节点
    if (carry != 0) {
        curr.next = new ListNode(carry);
    }

    // 返回虚拟头结点的下一个节点,即链表头结点
    return dummy.next;
}

Day4:删除链表中的节点

题目: 给定一个链表,删除链表中指定位置的节点。

图示示例:

删除链表中的节点示意图

代码示例:

public void deleteNode(ListNode node) {
    // 判断是否为尾节点
    if (node.next == null) {
        // 删除尾节点
        node.val = null;
    } else {
        // 将当前节点的值和下一个节点的值交换
        node.val = node.next.val;

        // 删除下一个节点
        node.next = node.next.next;
    }
}

结语

链表是算法学习中的重要数据结构,掌握链表操作是算法基础的体现。通过 LeetCode 练习和本文的讲解,相信您已对链表操作有了更深入的了解。坚持练习,勤于思考,您将成为算法学习的佼佼者!