LeetCode:删除链表的倒数第N个结点(中等)

自我小结

LeetCode题目:删除链表的倒数第N个结点(中等)

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

示例
给定一个链表: 1->2->3->4->5, 和 n = 2.
当删除了倒数第二个节点后,链表变为 1->2->3->5.
说明:给定的 n 保证是有效的。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

我的答案

方法一:快慢指针
1、第18行的while循环中,p=slow;和slow=slow->next;两者顺序不能颠倒,否则将删除待删结点的下一结点。
2、草稿纸上画一个简图能更好的理解过程。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
	struct ListNode* removeNthFromEnd(struct ListNode* head, int n){
    if (!head || n<=0) return NULL;         //非法处理
    struct ListNode *fast=head,*slow=head,*p=NULL;   //定义快慢指针和待删结点的前驱结点指针
    int i = 0;

    while (i<n){            //快指针先走n步
        fast = fast->next;
        i ++;
    }

    while (fast){               //当快指针没有走到最后时,快慢指针同时走1步
        p = slow;               //前驱结点赋值为慢指针,之后慢指针走1(不能颠倒)
        slow = slow->next;  
        fast = fast->next;      //若快指针的next为NULL时,慢指针的下一个接结点刚好为待删结点
    }

    if (p)      
        p->next = p->next->next;   //如果前驱结点存在,则删除待删结点
    else head = slow->next;     //否则说明待删结点为头结点

    return head;
}

方法二:按下标查找
第15行需要对结点进行判空,否则LeetCode的编译器将提示运行时错误。

	struct ListNode* removeNthFromEnd(struct ListNode* head, int n){
    int length=0,former=0;          //链表长度置0,待删结点的前一个结点下标置0
    struct ListNode *p = head,*res = head; //指针p用于遍历链表,指针res用于返回
    if (!head || n<=0) return NULL; //非法处理
    while (p){      //计算链表长度
        length ++;
        p = p->next;
    }

    former = length - n;        //待删结点的前一结点下标
    if (former == 0) res = head->next;      //说明待删结点为头结点
    for (int i=1; i<former; i++){      //否则指针走到待删结点前一结点
        head = head->next;
    }
    if (!head->next) return NULL;    //结点判空
    head->next = head->next->next;        //删除待删结点
    
    return res;
}

小结

1、首先想到的是第二种方法,通过对应下标来查找和删除,万万没想到也可以用双指针的方法来做。
2、通过LeetCode评论区得知一般带有间距问题的都可以用双指针来做,但要知道两颗指针应该怎么走才能满足题目条件;看来双指针确实是个很棒的方法,需要多加了解学习才能运用于实际。

(注:小白一枚,欢迎指正,多多包涵)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值