zoukankan      html  css  js  c++  java
  • 删除链表的倒数第N个节点(三种方法实现)

    删除链表的倒数第N个节点

    给定一个链表,删除链表的倒数第 个节点,并且返回链表的头结点。

    示例:

    给定一个链表: 1->2->3->4->5, 和 n = 2.
    
    当删除了倒数第二个节点后,链表变为 1->2->3->5.

    说明:

    给定的 n 保证是有效的。

    方法一解题思路:要求删除倒数第N个节点,可以先设两个指针同时指向链表的第一个节点,一个指针遍历链表统计出总共有多少个节点记为i,用总数减去N,即可以算出要删除的节点为正数第几个节点记为index=i-N,让另一个指针移动到index节点的前一个节点(如果要删除的节点不是第一个节点)。最后执行删除操作,如果要删除的节点为第一个节点,则需要修改头指针,反之,则直接删除即可

    /*解法一*/
    /**
    * Definition for singly-linked list.
    * struct ListNode {
    * int val;
    * struct ListNode *next;
    * };
    */
    struct ListNode* removeNthFromEnd(struct ListNode* head, int n) {
    int i = 1, j = i, index = 0;
    struct ListNode *p, *ptr;
    p = ptr = head;

    /*寻找到尾节点*/
    while (p->next != NULL)
    {
    p = p->next;
    i++;
    }

    /*确定要删除的节点为正数第几个节点*/
    index = i - n + 1;

    /*将另一个指针移动到index节点的前一个位置*/
    while (j + 1 < index)
    {
    ptr = ptr->next;
    j++;
    }
    /*删除操作,判断要删除的节点是否为第一个节点*/
    if (index != 1)
    {
    ptr->next = ptr->next->next; 
    return head;
    }
    else
    {

    return head = ptr->next;
    }
    }

    方法二解题思路:设置两个指针同时指向第一个节点,让第一个指针p向前移动n次,之后第二个指针p和指针ptr开始一起移动,直到p为空或者p->next为空,此时指针ptr指向要删除节点的前一个节点(如果要删除的不是第一个节点)。如果要删除的节点为第一个节点,则需要修改头指针,反之则直接删除即可。

    /*解法二*/
    /**
    * Definition for singly-linked list.
    * struct ListNode {
    * int val;
    * struct ListNode *next;
    * };
    */
    struct ListNode* removeNthFromEnd(struct ListNode* head, int n) {
    struct ListNode *p, *ptr = p = head;
    int i;

    /*让指针p向前走n步*/
    while (n-- > 0)
    {
    p = p->next;
    }

    /*当指针p走完n步以后,让指针p和ptr同时向前走,直到p走到最后一个节点,即p->next=NULL,整个过程p和ptr之间相隔n-1个节点*/
    while (p&&p->next != NULL)
    {
    ptr = ptr->next;
    p = p->next;
    }

    /*此时的ptr指向要删除节点的前一个节点,需要考虑删除的节点是否为首元节点*/
    if (p == NULL)
    return head = head->next;
    else
    {
    ptr->next = ptr->next->next;
    return head;
    }
    }

    方法三解题思路:方法三和方法四大同小异,首先当front非空时,让front移动n+1次,之后让behind跟着front一起移动(front和behind之间相隔n-1个节点),直到front为空。移动结束以后实行删除操作,删除操作和方法一和方法二一样。

    struct ListNode * removeNthFromEnd(struct ListNode * head,int n){

    struct ListNode* front = head;
    struct ListNode* behind = head;

    while (front != NULL) {
    front = front->next; /*指针front往前移动n+1次*/

    if (n-- < 0) behind = behind->next;  /*如果指针behind==0,表明需要删除的节点为第一个节点*/
    }

    /*循环过后,两个指针之间相隔n-1个节点*/
    if (n == 0) head = head->next;
    else behind->next = behind->next->next;
    return head;

    以上就是解题心得,如果有错误或有疑问欢迎大家指出,大家共同进步。

  • 相关阅读:
    Dungeon Master (BFS与DFS的应用)
    Broken Keyboard(模拟数组或者双重链表的运用)
    自己设置的纸牌游戏(简单数组栈和队列的设计)
    贪吃蛇(双重优先队列的综合运用)
    N!的阶乘附带简单大整数类的输入输出(暂时没有深入的了解)
    大整数乘法(Comba 乘法 (Comba  Multiplication)原理)
    建筑抢修(堆优先队列和贪心的结合)
    lower_bound()函数与quicksort()函数的简单掌握
    Long Jumps(二分查找lower_bound()函数的运用)
    团队队列(列和map结合的经典运用)
  • 原文地址:https://www.cnblogs.com/yangyalong/p/9744829.html
Copyright © 2011-2022 走看看