《LeetCode之每日一题》:109.删除链表的倒数第 N 个结点

Posted 是七喜呀!

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《LeetCode之每日一题》:109.删除链表的倒数第 N 个结点相关的知识,希望对你有一定的参考价值。

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


题目链接: 删除链表的倒数第 N 个结点

有关题目

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

进阶:你能尝试使用一趟扫描实现吗?

示例 2:

输入:head = [1], n = 1
输出:[]
示例 3:

输入:head = [1,2], n = 1
输出:[1]
提示:

链表中结点的数目为 sz
1 <= sz <= 30
0 <= Node.val <= 100
1 <= n <= sz

题解

方法一:计算链表长度

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
int getLength(struct ListNode* tmp){
    int len = 0;
    while(tmp){
        len++;
        tmp = tmp->next;
    }//统计节点总个数
    return len;
}

struct ListNode* removeNthFromEnd(struct ListNode* head, int n){
     struct ListNode* dummy = (struct ListNode*)malloc(sizeof(struct ListNode));//创建哑节点
    dummy->next = head;

    struct ListNode* cur = dummy;

    int sz = getLength(head);   

    int k = sz - n;//使得cur指向要删除节点的前一个位置
    while(k--){
       cur = cur->next;
    }
    cur->next = cur->next->next;

    struct ListNode* ans = dummy->next;
    free(dummy);//动态开辟内存使用完毕后注意关闭
    return ans;
}


方法二:栈

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct Stack{
    struct ListNode* val;
    struct Stack* next;
};

struct ListNode* removeNthFromEnd(struct ListNode* head, int n){
    struct ListNode* dummy = (struct ListNode*)malloc(sizeof(struct ListNode));
    dummy->val = 0, dummy->next = head;//val值可以不用管

    struct ListNode* cur = dummy;
    struct Stack* stk = NULL;//栈
    while(cur){
        struct Stack* tmp = (struct Stack*)malloc(sizeof(struct Stack));

        tmp->val = cur, tmp->next = stk;//栈先进后出体现在这两步
        stk = tmp;
        
        cur = cur->next;
    }

    for (int i = 0; i < n; i++){//弹出第n个节点
        struct Stack* tmp = (struct Stack*)malloc(sizeof(struct Stack));
        tmp = stk->next;
        free(stk);
        stk = tmp;
    }

    struct ListNode* pre = stk->val;
    pre->next = pre->next->next;

    struct ListNode* ans = dummy->next;
    free(dummy);//动态开辟内存使用完毕后注意关闭
    return ans;
}


方法三:双指针
参考官方题解

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* removeNthFromEnd(struct ListNode* head, int n){
    struct ListNode* dummy = (struct ListNode*)malloc(sizeof(struct ListNode));
    dummy->val = 0, dummy->next = head;//val值可以不用管

    struct ListNode* first = head;
    struct ListNode* second = dummy;

    for (int i = 0; i < n; i++){
        first = first->next;
    }//与second相差n个节点

    while(first){
        first = first->next;
        second = second->next;
    }

    second->next = second->next->next;
    struct ListNode* ans = dummy->next;
    free(dummy);
    return ans;
}

以上是关于《LeetCode之每日一题》:109.删除链表的倒数第 N 个结点的主要内容,如果未能解决你的问题,请参考以下文章

《LeetCode之每日一题》:288.删除排序链表中的重复元素

《LeetCode之每日一题》:288.删除排序链表中的重复元素

《LeetCode之每日一题》:99.删除排序链表中的重复元素 II

《LeetCode之每日一题》:286.移除链表元素

每日一题之LeetCode237删除链表中的节点876链表的中间节点

《LeetCode之每日一题》:286.移除链表元素