算法day12 删除链表的倒数第N个节点

题目描述

思路一:算正序位置删除
链表的倒数第N个元素即是正序(len-n+1),(我们这里假设链表的长度为len),所以我们可以将这题的思路由找倒数转表为找正数的位置。接下来的整个操作就与普通的删除链表节点没有什么大差异。

代码如下:

ListNode* removeNthFromEnd(ListNode* head, int n) {
   
    ListNode dummyhead(0); //虚拟头节点
    dummyhead.next = head;
    ListNode *cur = head;
    int len = 0;
    while(cur){
        len++;
        cur = cur -> next;
    }
    cur = &dummyhead;
    int cnt = len - n ;
    while(cnt--){
        cur = cur -> next;
    }
    
    ListNode *s = cur -> next;
    cur -> next = cur -> next->next;
    delete s;
    s = nullptr;

   return dummyhead.next;

}

时间复杂度:O(n)
空间复杂度:O(1)

思路二:快慢指针

除了第一种思路外,我们也可以尝试设置快慢指针的方式。我们使快指针与慢指针位置相差n,这样快指针迭代到末尾时,慢指针就会迭代到倒数第n-1个位置,接下来进行删除链表的节点的操作即可。这个思路相较于第一个思路具有时间上的优化,它不必再进行一次完全的链表遍历来获得链表长度。

代码如下:

  ListNode* removeNthFromEnd(ListNode* head, int n) {
    ListNode dummyhead(0);
    dummyhead.next = head;
    ListNode *fast = &dummyhead;
    while(n--){
        fast = fast -> next;
    }
    ListNode *slow = &dummyhead;
    while(fast->next){
        fast = fast -> next;
        slow = slow -> next;
    }
    ListNode *s = slow -> next;
    slow -> next = slow -> next -> next;
    delete s;
    s = nullptr;

    return dummyhead.next;
}

时间复杂度:O(n)
空间复杂度:O(1)

END

posted on 2025-04-16 14:19  sakura430  阅读(8)  评论(0)    收藏  举报