《从头再来》每日一题.203 移除链表元素

给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。

这一道题和剑指offer.18删除链表的结点不同,本题是存在多个需要删除的节点,而offer.18则只有一个节点需要删除,所以删除后直接跳出循环即可。而本题需要遍历到链表的最后,才能达到删除所有满足要求的节点的目的。

所以首先想到的是利用双指针来解题,后续可能会考虑以下用栈解决,理论上用栈也是可以解决的。

方法一、双指针

总体思路是定义两个指针,一个位置指针cur用于在链表节点上移动,一个记录指针record用于记录未被删除的节点。特判情况就是整个链表为空,以及头节点就是需要删除的节点的情况(此处因为可能存在多个需要删除的节点,所以需要循环判断头节点是不是需要删除的节点),然后就是普通节点的判断。如果cur是要删除的节点,则记录指针record的next应为cur的next,再移动cur;如果cur不是需要删除的节点,则record记录下cur的位置,cur再后移。最后返回头节点,就是保留下来的链表。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        //首先特判,如果链表为空,直接返回空
        if(head == nullptr) return nullptr;
        //然后循环判断头节点是否是要删除的结点
        while(head->val == val){
            if(head->next != nullptr)   head = head->next;//如果头节点时要删除的结点且头节点的下一位不为空,则头节点后移一位
            else return nullptr;//如果头节点时要删除的结点,且下一位为空,则返回空
        }

        //定义两个指针,一个用于移动位置,一个用于记录未删除的结点
        ListNode *cur = head;//位置
        ListNode *record = head;//记录
        //以下情况发生在头节点一定不会删除
        while(cur != nullptr){
            //无论是否是删除的情况,一定要先记录,再移动位置
            if(cur->val == val){//当前结点需要删除
                record->next = cur->next;
                cur = cur->next;
            }
            else{
                record = cur;
                cur = cur->next;
            }
        }
        return head;
    }
};

以上,已经解释的比较清楚了。

《从头再来》

posted @ 2021-06-05 17:32  丶原来是枝知啊i  阅读(89)  评论(0)    收藏  举报