大家好,我是开车的阿Q,自动驾驶的时代已经到来,没时间解释了,快和阿Q一起上车。作为自动驾驶系统工程师,必须要有最好的C++基础,让我们来一起刷题吧。

题目考察的知识点

这道题目主要考察链表的遍历、指针操作以及链表节点的删除和插入操作。

题目解答方法的文字分析

题目要求将链表中的倒数第 n 个节点移到链表的末尾。我们可以通过使用两个指针来实现这个目标。首先,一个指针先移动 n 步,然后两个指针同时向后移动,直到第一个指针到达链表的末尾。此时,第二个指针指向的节点就是倒数第 n 个节点,我们将它从链表中删除,并将它插入到链表的末尾。

举个例子,假设链表为 1 -> 2 -> 3 -> 4 -> 5,n = 2。首先,第一个指针移动 2 步,指向节点 3,然后两个指针同时向后移动,直到第一个指针指向节点 5。此时,第二个指针指向节点 4,我们将节点 4 从链表中删除,并将它插入到节点 5 后面,得到新的链表 1 -> 2 -> 3 -> 5 -> 4。

本题解析所用的编程语言

C++

完整且正确的编程代码

/**
 * struct ListNode {
 *	int val;
 *	struct ListNode *next;
 *	ListNode(int x) : val(x), next(nullptr) {}
 * };
 */
class Solution {
public:
    ListNode* moveNthToEnd(ListNode* head, int n) {
        if (head == nullptr || n <= 0) {
            return head;
        }

        ListNode* dummy = new ListNode(0);  // 添加一个哑节点简化操作
        dummy->next = head;
        ListNode* slow = dummy;
        ListNode* fast = dummy;

        // 第一个指针先移动 n 步
        for (int i = 0; i <= n; ++i) {
            if (fast == nullptr) {
                return head; // 链表长度小于 n,直接返回原链表
            }
            fast = fast->next;
        }

        // 同时移动两个指针,直到第一个指针到达链表末尾
        while (fast != nullptr) {
            slow = slow->next;
            fast = fast->next;
        }

        // 此时第二个指针指向倒数第 n 个节点,将其从链表中删除
        ListNode* nthNode = slow->next;
        slow->next = nthNode->next;

        // 将倒数第 n 个节点插入到链表末尾
        ListNode* current = dummy;
        while (current->next != nullptr) {
            current = current->next;
        }
        current->next = nthNode;
        nthNode->next = nullptr;

        ListNode* newHead = dummy->next;
        delete dummy; // 释放哑节点内存

        return newHead;
    }
};

您的关注、点赞、收藏就是我创作的动力,三连支持阿Q![![图片说明](https://uploadfiles.nowcoder.com/images/20220720/231521985_1658328390978/2C37BCD128F43FC7567EEF5450D7D0CF "图片标题") ](https://www.nowcoder.com/users/231521985) !