删除链表——从LeetCode题海中总结常见套路

删除链表类的题目不难,全是套路,刷过就很简单

目录

删除链表结点套路总结:

LeetCode203.移除链表元素

LeetCode面试题18.删除链表的节点

LeetCode237.删除链表中的结点

LeetCode83.删除排序链表中的重复元素

LeetCode82.删除排序链表中的重复元素II

面试题02.01.移除重复节点


删除链表结点套路总结:

  1. 虚拟新建虚拟头结点dummy
  2. dummy->next = head;
  3. 新建领先结点pre = dummy;因为我们不操作dummy和head
  4. 对pre进行常规操作即可

注意:

  • 注意要新建一个头结点,称为dummyhead
  • 新建结点,不能直接在原来的结点上操作!
  • 删除下一个结点的语句是 cur->next = cur->next->nex
  • 一定要定义指针指向原来的结点操作,否则不管怎样操作原来的结点都是不变的啊!

  • 注意判断的时候,不能写成dummy->val的陷阱中,这样会出现最后一个结点无法删除!

LeetCode203.移除链表元素

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        if(head==NULL)
            return NULL;
        ListNode* dummy = new ListNode(-1);//虚拟头结点
        dummy->next = head;//连接
        ListNode* pre = dummy;//前置结点,领先一步
        while(pre->next){
            if(pre->next->val==val)
                pre->next = pre->next->next;
            else 
                pre = pre->next;
        }
        return dummy->next;//返回虚拟头结点
    }
};

LeetCode面试题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) {
        ListNode* dummy = new ListNode(0);
        dummy->next = head;
        if(head->val==val)//如果删除的值位于头部
            return head->next;//其实我没有想懂这种情况为什么要单独领出来判断
        while(dummy->next->val!=val){//不能写成dummy->val的陷阱中,这样会出现最后一个结点无法删除
            dummy = dummy->next;
        }
        dummy->next = dummy->next->next;
        return head;
    }
};

LeetCode237.删除链表中的结点

题目一开始没读懂,看了评论区才明白,这道题还是有点鸡贼……

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

或者一行代码:

*node = *(node->next);

LeetCode83.删除排序链表中的重复元素

这里因为是有序的,所以重复元素肯定是挨在一起的,不想下一题要用set,所以这里处理起来就很简单

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* deleteDuplicates(ListNode* head){
        ListNode* cur=head;
        while(cur&&cur->next){
            if(cur->next->val!=cur->val)
                cur = cur->next;
            else//是重复
                cur->next = cur->next->next;
        }
        return head;
    }
};

LeetCode82.删除排序链表中的重复元素II

一定要注意定义dummy和pre结点的重要性!——这是链表题的常规套路!

pre可以解决单向链表中无法指向前结点的问题,dummy用于解决定义一个整体链表的头结点的问题

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    //思路:遍历链表,pre用来指向不重复节点
    ListNode* deleteDuplicates(ListNode* head) {
        if(!head||!head->next)return head;
        ListNode *dummy=new ListNode(-1);
        dummy->next=head;
        ListNode *pre=dummy;
        while(head&&head->next){
            if(head->val!=head->next->val){//head与head->next节点值不相等,pre指向head,也就是指向不重复值
                pre=head;
                head=head->next;
            }
            else{
                //head为重复值子链表的最后一个节点,比如1->1->1->2的最后一个1
                while(head&&head->next&&head->val==head->next->val){
                    head=head->next;
                }
                //pre连接重复值子链表的之后第一个节点
                pre->next=head->next;
                head=head->next;
            }
        }
        return dummy->next;
    }
};

面试题02.01.移除重复节点

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* removeDuplicateNodes(ListNode* head) {
        ListNode* cur = new ListNode(-1);//注意不能赋值为0元素,因为后面可能会出现0元素
        cur->next = head;
        set<int> s;
        while(cur&&cur->next){
            if(s.find(cur->next->val)==s.end()&&cur->next->val!=cur->val){//不是重复
                s.insert(cur->val);
                cur = cur->next;
            }else{//是重复
                cur->next = cur->next->next;
            }
        }
        return head;
    }
};
发布了377 篇原创文章 · 获赞 344 · 访问量 17万+

猜你喜欢

转载自blog.csdn.net/qq_41895747/article/details/104848134