删除给定索引处的链表末尾节点。

huangapple go评论96阅读模式
英文:

Delete node from the end of the linked list for the given index

问题

我正在尝试解决LeetCode问题19. 删除链表的倒数第N个节点

以下是我编写的代码:

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        int count = 0;
        while (head->next != NULL){
            head = head->next ;
            count++;
        }
        int len;
        len = count - n ;
        ListNode* curr = head; 
        for(int i = len ; i > 0 ; i--){
            curr = curr->next;
        }
        curr->next = curr->next->next;
        return head;
    }
};

我遇到了这个错误:

第23行:字符26:运行时错误:在类型为'ListNode'的空指针内部访问成员 (solution.cpp)

总结:UndefinedBehaviorSanitizer:undefined-behavior prog_joined.cpp:32:26

有人能告诉我代码中有什么问题,导致它引发此错误吗?

英文:

I'm trying to solve LeetCode problem 19. Remove Nth Node From End of List
:

> Given the head of a linked list, remove the n<sup>th</sup> node from the end of the list and return its head.
> ### Example 1
> 删除给定索引处的链表末尾节点。
>
> Input: head = [1,2,3,4,5], n = 2
>
> Output: [1,2,3,5]

This is the code I wrote:

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        int count = 0;
        while (head-&gt;next!=NULL){
            head = head -&gt; next ;
            count++;
        }
        int len;
        len = count - n ;
        ListNode* curr = head; 
        for(int i =len ; i &gt; 0 ; i--){
            curr = curr-&gt;next;
        }
        curr-&gt;next = curr-&gt;next-&gt;next;
        return head;

    }
};

I get this error:

> Line 23: Char 26: runtime error: member access within null pointer of type 'ListNode' (solution.cpp)
>
> SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior prog_joined.cpp:32:26

Can someone tell what is wrong in the code, that it raises this error?

答案1

得分: 0

这是经过翻译后的内容:

有一些问题:

  • 第一个循环使 head 引用列表中的最后一个节点。但这意味着你的第二个循环将从那里开始,而不是从列表的第一个节点开始。因此,在第二个循环的第一次迭代中,curr = curr->next 将会将 nullptr 赋给 curr,并且它的第二次迭代将遇到你看到的错误。你不应该使用 head 作为遍历列表的工具。使用一个单独的变量来进行遍历。

  • 当要删除的节点是列表中的最后一个节点时,会出现类似的错误。在这种情况下,表达式 curr->next->next 将引发错误。在这种情况下,curr->next 为空。你应该处理这个边界情况,首先验证 curr->next 是否为空,并相应地采取措施。

  • 你的代码没有考虑到第一个节点需要被删除的情况,这意味着你必须返回 head 的后继节点。

(不是问题,但在C++代码中不应该使用 NULL,应该使用 nullptr)。

这是经过修正以解决这三个问题的代码:

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        int count = 0;
        ListNode* curr = head; // 使用一个不同的变量进行遍历
        while (curr->next) { // 不要使用 NULL
            curr = curr->next;
            count++;
        }
        int len;
        len = count - n;
        if (len < 0) { // 处理移除第一个节点的情况
            return head->next;
        }
        curr = head;
        for (int i = len; i > 0; i--) {
            curr = curr->next;
        }
        // 处理移除最后一个节点的情况(当 curr->next 为 nullptr 时)
        curr->next = curr->next ? curr->next->next : nullptr;
        return head;
    }
};
英文:

There are a few issues:

  • The first loop makes head reference the last node in the list. But that means your second loop will start from there, not from the first node of the list. And so in the first iteration of the second loop, curr = curr-&gt;next will assign nullptr to curr, and its second iteration will run into the error you saw. You should not use head as a tool to traverse the list. Use a separate variable for that.

  • The similar error will occur when the node to remove is the last node in the list. In that case the expression curr-&gt;next-&gt;next will raise the error. curr-&gt;next is null in that case. You should deal with this boundary case and first verify whether curr-&gt;next is null and act accordingly.

  • Your code does not foresee the case where the first node needs to be removed, which means you have to return the successor of head.

(Not a problem, but NULL should not be used in C++ code, use nullptr).

Here is your code with the corrections needed to fix these three issues:

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        int count = 0;
        ListNode* curr = head; // Use a different variable for the traversal
        while (curr-&gt;next) { // Don&#39;t use NULL
            curr = curr -&gt; next ;
            count++;
        }
        int len;
        len = count - n;
        if (len &lt; 0) { // Deal with removal of first node
            return head-&gt;next;
        }
        curr = head; 
        for (int i = len ; i &gt; 0 ; i--) {
            curr = curr-&gt;next;
        }
        // Deal with removal of last node (when curr-&gt;next is nullptr)
        curr-&gt;next = curr-&gt;next ? curr-&gt;next-&gt;next : nullptr;
        return head;
    }
};

huangapple
  • 本文由 发表于 2023年6月9日 00:46:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/76434063.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定