LeetCode No.19 Remove Nth Node From End of List

来源:互联网 发布:简述云计算 编辑:程序博客网 时间:2024/05/18 17:59

题目:给定一个链表,删除链表的倒数第n的节点,并返回其头节点。

例子:1->2->3->4->5,n = 2,那么返回结果应该是:1->2->3->5

注:给定的n一个是一个合法的值。

       尝试在一次遍历中完成。


我们知道,单向链表是不可能倒着遍历的(除非借助栈这样的结构,并且需要额外的非常数的存储空间),那么我们如何在一次遍历中确定我们当前遍历到的点就是倒数第n个节点呢?显然我们需要一些标识,使用双指针法可以做到。

思路:

  • 使用两个指针,初始时,第一个指针指向头节点,第二个指针指向第一个指针之后的n个节点;
  • 开始遍历,两个指针每次都前进一步;
  • 当第二个指针指向最后一个节点时,第一个指针之后的节点就是我们要删除的节点;
思路并不复杂,但是这是一道单向链表的题,操作指针我们就要小心了!那么这道题有哪些需要注意的地方呢?我们通过代码来分析:
函数的形参有两个,一个是指针,指向链表第一个节点;一个是整形变量,代表要删除的位置,那么针对这两个参数就可以知道有下面这几点需要注意:
  • 如果指针为nullptr,程序会不会崩溃?
  • 如果n值不合法,程序会不会崩溃?(这道题里说了n值一定合法,不过我们还是要养成好习惯!)
/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:    ListNode* removeNthFromEnd(ListNode* head, int n)     {        //这里需要判断,否则会引起程序崩溃        if(!head || n <= 0) return nullptr;        //我们使用两个指针来确定倒数第n的节点是谁        //当第二个指针是链表的最后一个节点的时候,第一个指针的next就是我们要删除的节点        ListNode *first = head;        ListNode *second = first;        for(int i = 0; i < n; ++i)        {            second = second->next;            //处理n大于链表长度的情况            if(!second && i < n - 1) break;        }                   //这是n等于链表长度的情况,也就是我们要删除的是第一个节点        if(second == nullptr)        {            head = head->next;            return head;        }                //开始遍历链表知道第二个指针到达链表最后一个节点        while(second->next != nullptr)        {            first = first->next;            second = second->next;        }        //删除第一个指针所指节点的next        first->next = first->next->next;                return head;    }};

下面是运行结果:



原创粉丝点击