《从头再来》每日一题.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; } };
以上,已经解释的比较清楚了。
《从头再来》

浙公网安备 33010602011771号