《从头再来》剑指offer.18 删除链表的结点

Posted azie

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《从头再来》剑指offer.18 删除链表的结点相关的知识,希望对你有一定的参考价值。

给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。

返回删除后的链表的头节点。(注意此题说明了只删除一个结点)

 

最常规的方法:单指针。总体思想是,如果当前节点的下一个节点为要删除的节点,则当前节点的下一个节点变为删除前下一个节点的下一个节点。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* deleteNode(ListNode* head, int val) {
        if(head == nullptr) return nullptr;//如果当前链表为空,返回空
        if(head->val == val)    return head->next;//删除的节点是头节点

        ListNode *cur = head;
        while(cur != nullptr){
        //cur肯定不是要删除的节点,因为现在是头节点,所以是判断下一个节点是不是要删除的节点
if(cur->next->val == val){ cur->next = cur->next->next; break;//找到并删除了结点,跳出循环(找到过后一定要跳出循环) } else //没找到需要删除的结点,结点后移一位 cur = cur->next; } return head; } };

第二种方法:双指针(可能比单指针好理解一点)。两个指针都指向头节点cur和pre,然后cur指针默默的往下移动,寻找可能删除的节点,pre指针记录cur指针被删除前的一个节点。如果cur指针没到链表的最后,那么就判断它的值,如果不会删除,则使用pre记录下来,并让cur后移一位。如果cur被删除了,则pre指针的后一位等于cur指针的后一位,并且跳出循环

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* deleteNode(ListNode* head, int val) {
        if(head == nullptr) return nullptr;
        if(head->val == val)    return head->next;

        ListNode *cur = head;//当前节点,可能要删除
        ListNode *pre = head;//保留上一个未删除的节点
        while(cur != nullptr){
            if(cur->val != val){
                pre = cur;
                cur = cur->next;
            }
            else{
                pre->next = cur->next;
                break;//记住,找到了删除的节点,删除后一定要break跳出节点
            }
        }
        return head;
    }
};

第三种方法:利用链表的天然递归性质。递归的调用删除节点的方法,如果当前节点删除了,则返回下一个节点。(所以递归的终止条件是,如果当前节点为空,则直接返回空;如果当前节点为要删除的节点,则返回下一个节点。)

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* deleteNode(ListNode* head, int val) {
        if(head == nullptr) return nullptr;
        if(head->val == val)    return head->next;

        head->next = deleteNode(head->next,val);
        return head;
        //return head->val == val? head->next:head;
    }
};

 

以上是关于《从头再来》剑指offer.18 删除链表的结点的主要内容,如果未能解决你的问题,请参考以下文章

剑指offer18.删除链表中重复节点

剑指offer18删除链表的(重复)节点

算法剑指 Offer 18. 删除链表的节点

剑指Offer打卡18. 删除链表的节点

剑指Offer打卡18. 删除链表的节点

剑指 Offer 18. 删除链表的节点