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

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
     ListNode* dummyHead = new ListNode(0);
        dummyHead->next = head;

        ListNode* p = dummyHead;
        ListNode* q = dummyHead;
        for( int i = 0 ; i < n + 1 ; i ++ ){
            q = q->next;
        }

        while(q){
            p = p->next;
            q = q->next;
        }

        ListNode* delNode = p->next;
        p->next = delNode->next;
        delete delNode;

        ListNode* retNode = dummyHead->next;
        delete dummyHead;

        return retNode;
        
    }
};

这是利用哑节点,创立一个节点,指向head的前面,然后fast开始遍历n+1次,而slow接着遍历,当fast=NULL的时候,以前是slow正好到达倒数第k个位置,现在fast提前走了一个位置,所以提前一步到达链表末尾,所以slow也是到倒数第k个节点的前一个节点,这样就好办了,找到了前一个节点. 如果不这么做的话,只是找到当前待删除的节点,只能使用移花接木方法了…如下:

/**
* Definition for singly-linked list.
* struct ListNode {
*     int val;
*     ListNode *next;
*     ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution77{
public:
	ListNode* removeNthFromEnd(ListNode* head, int n) {

		if (head == NULL)
		{
			return NULL;
		}
		ListNode*slow = head;
		ListNode*fast = head;
		for (int i = 0; i < n;i++)
		{
			fast = fast->next;
		}
		if (fast == NULL)
		{
			head = head->next;
			return head;
		}
		while (fast!=NULL)
		{
			fast = fast->next;
			slow = slow->next;
		}
		//此时slow是倒数第n个节点

		if (slow == head)
		{
			head = slow->next;
			return head;
		}

		if (slow->next == NULL)//这个判断很重要,如果不判空的话,那么下次delete_node->next就崩溃
		{
			ListNode*cur = head;
			while (cur->next != slow)
			{
				cur = cur->next;//为了找到最后一个节点(也就是当前待删节点的前一个节点,将它指向空.)
			}
			cur->next = slow->next;
			delete slow;
			return head;
		}
		ListNode*delete_node = slow->next;//如果是倒数第一个节点就不行,delete_node已经是NULL节点了,对空节点->next肯定不行
		slow->val = delete_node->val;
		slow->next = delete_node->next;
		delete delete_node;
		return head;
	}
};
class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        if(head==NULL)
            return NULL;
        ListNode* fast=head;
        ListNode* slow=head;
        for(int i=0;i<n;i++)
        {
            fast=fast->next;
        }
        if(fast==NULL)//判断指针移动过了head,比如倒数第5个节点,一共4个
        {
            head=head->next;
            return head;
        }
        while(fast->next!=NULL)//假设3个节点,n=2,倒数第二个,那么fast直接移动到倒数第一个元素上,判断next为空,说明如果fast再移动一步的话,那么slow的位置就是倒数第k个节点,所以我不移动了,直接不进行循环.那么slow就是倒数第k个节点的前一个节点,我只需执行slow->next=slow-next->next;就可以了.一步到位,绝!
        {
            fast=fast->next;
            slow=slow->next;
        }
        slow->next=slow->next->next;
        return head;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值