力扣刷题之删除链表倒数第n个节点

##力扣刷题之删除链表倒数第n个节点

示例:

给定一个链表: 1->2->3->4->5, 和 n = 2.

当删除了倒数第二个节点后,链表变为 1->2->3->5.
说明:

给定的 n 保证是有效的。

进阶:

你能尝试使用一趟扫描实现吗

来源:力扣(LeetCode)

struct ListNode* removeNthFromEnd(struct ListNode* head, int n){
    struct ListNode *Head=head;
    struct ListNode *aimNode=NULL;
    int m;
    int size=0;                          //链表长度
    if(head->next==NULL){
        return Head->next;
    }
    for(head;head!=NULL;head=head->next,size=size+1){
    }
    head=Head;
    m=size-n;
    if(m==0)                               //删除头结点
    {
        Head=Head->next;
        return Head;
    }  
    if(n==1){                              //删除最后一个节点
        for(head;head->next->next!=NULL;head=head->next){
        }
        head->next=NULL;
        return Head;
    }
    for(int i=0;i<m-1;i++){
        head=head->next;
    }
    head->next=head->next->next;
    return Head;
    }

解题思想:
没考虑只用一次便利就解决问题,首先使用的是比较传统的思想,先编译一遍链表,得到链表的长度size,然后利用所得长度减去n得到需要删去的节点,得到需要删除节点的前一个节点操作必要容易,所以遍历的时候只遍历到前一个节点,然后对链表进行操作。

注意:
在代码实现的过程中,遇到两种特殊情况需要处理。
1.删除头结点的情况。
2.删除最后一个节点。

代码2:

struct ListNode* removeNthFromEnd(struct ListNode* head, int n){
 struct ListNode *first=NULL;
	struct ListNode *second=NULL;
    struct ListNode *thead=malloc(sizeof(struct ListNode));
    thead->val=0;thead->next=head;
	first=head;second=thead;
	for(int i=0;i<n;i++){
		first=first->next;
	}
	while(first){
		first=first->next;
		second=second->next;
	}
	second->next=second->next->next;
    struct ListNode *ans=thead->next;
    free(thead);
	return ans;
}

解题思想2:
看过题解后,知道了只需要一次遍历就能解题的解题思想。
利用快慢指针first和second,先让first遍历n次,再让second开始遍历,这样
first和second之间相隔n-1个节点,first和second就相差n,当first遍历到链表结尾的时候,second就刚好到需要删除的节点。

注意:
1.让second遍历到需要删除的节点的前一个节点更好操作,所以可以让增加一个空节点其next指向头节点,second开始指向这个节点即thead->next=head,second=thead;这样当first指向链表结尾的时候,second指向需要删除节点的前一个节点。但是不要让first多遍历一次,这样在某些情况时会导致first遍历到尾结->next->next,导致报错。
2.考虑删除头节点的情况。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值