LeetCode | Remove Nth Node From End of List(移除链表中倒数第n个结点)


题目:

Given a linked list, remove the nth node from the end of list and return its head.

For example,

   Given linked list: 1->2->3->4->5, and n = 2.

   After removing the second node from the end, the linked list becomes 1->2->3->5.

题目解析:

这道题目和【剑指offer】面试题15:链表中倒数第k个结点很相像。只是这里要删除结点,要考虑的情况更多一点。

虽然这道题目比较容易,但是有很多地方要注意:输入的是空指针怎么办?输入的是0怎么处理?(为0的时候,n-1不是-1,而是最大的正数,因为变量设为unsigned)当链表的个数正好是n个的时候怎么处理?那么就要删除第一个结点,头指针的值会改变。

基于以上的情况分析,才能写出可靠的代码

LinkList RemoveNth(LinkList *head,unsigned int n)
{
    if(n == 0)
        return *head;
    if(*head == NULL){
        printf("list is NULL\n");
        return NULL;
    }
    LinkList p = *head;

    for(int i = 0;i < n-1;i++){
        p = p->next;
        if(!p){
            printf("lenth < n\n");
            exit(1);
        }
    }
    if(p->next == NULL){    //证明长度刚好是n
        p = *head;
        *head = (*head)->next;
        free(p);
        return *head;
    }
    p = p->next;
    LinkList q = *head; //此时的q指向的是倒数第n个结点的父节点!
    while(p->next){
        p = p->next;
        q = q->next;
    }
    p = q->next;    //p重新赋值为q的子节点
    q->next = p->next;
    free(p);
    return *head;
}

完整的程序代码:

#include <stdio.h>
#include <stdlib.h>

typedef struct LNode{
    int data;
    struct LNode *next;
}ListNode,*LinkList;

void CreateList(LinkList *head,int n)
{
    for(int i = 0;i < n;++i){
        LinkList p = (LinkList)malloc(sizeof(ListNode));
        if(p == NULL){
            printf("malloc error\n");
            exit(1);
        }
        scanf("%d",&(p->data));
        p->next = *head;
        *head = p;
    }
}

void DestoryList(LinkList *head)
{
    if(*head == NULL)
        return ;
    LinkList p = *head;
    LinkList q = p->next;

    while(q){
        free(p);
        p = q;
        q = p->next;
    }
    free(p);
    *head = NULL;
}

void PrintList(LinkList head)
{
    LinkList p = head;
    while(p){
        printf("%d ",p->data);
        p = p->next;
    }
    printf("\n");
}

LinkList RemoveNth(LinkList *head,unsigned int n)
{
    if(n == 0)
        return *head;
    if(*head == NULL){
        printf("list is NULL\n");
        return NULL;
    }
    LinkList p = *head;

    for(int i = 0;i < n-1;i++){
        p = p->next;
        if(!p){
            printf("lenth < n\n");
            exit(1);
        }
    }
    if(p->next == NULL){    //证明长度刚好是n
        p = *head;
        *head = (*head)->next;
        free(p);
        return *head;
    }
    p = p->next;
    LinkList q = *head; //此时的q指向的是倒数第n个结点的父节点!
    while(p->next){
        p = p->next;
        q = q->next;
    }
    p = q->next;    //p重新赋值为q的子节点
    q->next = p->next;
    free(p);
    return *head;
}


int main()
{
    LinkList head = NULL;
    int n;

    while(scanf("%d",&n) != EOF){
        CreateList(&head,n);
        PrintList(head);
        printf("input the delete num:");
        scanf("%d",&n);
        RemoveNth(&head,n);
        PrintList(head);
        DestoryList(&head);
    }

    return 0;
}

点赞