【刷题记录】移除链表元素

简介: 【刷题记录】移除链表元素

本系列博客为个人刷题思路分享,有需要借鉴即可。

注:部分思路借鉴自程序员小熊

链接:https://leetcode.cn/problems/remove-linked-list-elements/solutions/341875/203-yi-chu-lian-biao-yuan-su-you-ya-di-gui-c-yu-ya/

来源:力扣(LeetCode)

1.目录大纲:

2.题目链接:

T1:LINK

3.详解思路:

T1:

思路1:双指针:遍历原链表,遇到val就执行删除val节点的操作

分析1:时间复杂度:O(N) 结论:yes

struct ListNode* removeElements(struct ListNode* head, int val){
    
    //处理head == val 的情况,使head!=val
    while (NULL != head && head->val == val) 
    {
        head = head->next;
    }
    
    struct ListNode* cur = head;
    struct ListNode* pre = head;
    while (cur != NULL) {
        if (cur->val == val) {
            //跳跃
            pre->next = cur->next;
        } else {
            //下一个跟进cur
            pre = cur;
        }
        //cur不断向前走
        cur = cur->next;
    }
    return head;
}

当然上面所说的思路也可以这样写:

struct ListNode* removeElements(struct ListNode* head, int val){
    
    //处理*head == val 的情况,使*head!=val
    while (NULL != head && head->val == val) 
    {
        head = head->next;
    }
    
    if(head == NULL)
    {
        return NULL;
    }
    struct ListNode* cur = head->next;//如果head为空链表这样写不合法
    struct ListNode* pre = head;
    while (cur != NULL) {
        if (cur->val == val) {
            //跳跃
            pre->next = cur->next;
        } else {
            //下一个跟进cur
            pre = cur;
        }
        //cur不断向前走
        cur = cur->next;
    }
    return head;
}

思路2:虚拟哨兵

分析:时间复杂度:O(N) 结论:yes

struct ListNode* removeElements(struct ListNode* head, int val){
    
    struct ListNode* dummyHead = malloc(sizeof(struct ListNode));
    
    dummyHead->next = head;
    struct ListNode* cur = dummyHead;
    while (cur->next != NULL) {
        if (cur->next->val == val) {
            
            cur->next = cur->next->next;
        } else {
            cur = cur->next;
        }
    }
    return dummyHead->next;
}

思路3:重新构造一个新链表

分析3:时间复杂度:O(N) OK

struct ListNode* removeElements(struct ListNode* head, int val){
    
    //定义新链表的头尾指针
    struct ListNode* newHead = NULL;
    struct ListNode* newTail = NULL;
    //
    struct ListNode* pcur = head;
    while(pcur)
    {
        //不是val,尾插到新链表
        if(pcur->val!=val)
        {
            if(newHead == NULL)
            {
                //链表为空
                newHead = newTail = pcur;
            }
            else//链表不为空
            {
                newTail->next = pcur;
                newTail = newTail->next;//更新尾节点
            }
        }
        //更新pcur指针
        pcur = pcur->next;
    }
    //加上null
        if(newTail)
        {
            newTail->next = NULL;
        }
    //返回
        return newHead;
}

思路4:单指针法

思路分析4:yes

struct ListNode* removeElements(struct ListNode* head, int val){
    while (NULL != head && head->val == val) {
        head = head->next;
    }
    if (NULL == head) {
        return head;
    }
    struct ListNode* pre = head;
    while (pre->next != NULL) {
        //找到值为 val 的节点,并将其删除 
        if (pre->next->val == val) {
            pre->next = pre->next->next;   
        } else {
           //继续遍历
            pre = pre->next;
        }
    }
    return head;
}
作者:程序员小熊
链接:https://leetcode.cn/problems/remove-linked-list-elements/solutions/341875/203-yi-chu-lian-biao-yuan-su-you-ya-di-gui-c-yu-ya/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

思路5:递归

思路分析5:可行。

struct ListNode* removeElements(struct ListNode* head, int val){ 
    //递归指向NULL时候终止,开始回归
    if (NULL == head) {
        return head;
    }     
  //递归结果暂时存储
    head->next = removeElements(head->next, val);
    //三目操作符简化
    return head->val == val ? head->next : head;
}
struct ListNode* removeElements(struct ListNode* head, int val){ 
    if (NULL == head) {
        return head;
    }     
    /* 删除头节点后所有值为 val 的节点 */
    struct ListNode* res = removeElements(head->next, val);
    /* 头节点是待删除的节点 */
    if (head->val == val) {
        return res;
    /* 头节点不是待删除的节点,头节点后面挂接已处理的链表(更短的) */
    } else {
        head->next = res;
        return head;
    }
}
作者:程序员小熊
链接:https://leetcode.cn/problems/remove-linked-list-elements/solutions/341875/203-yi-chu-lian-biao-yuan-su-you-ya-di-gui-c-yu-ya/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

完。

相关文章
|
2月前
|
索引 Python
【Leetcode刷题Python】328. 奇偶链表
在不使用额外空间的情况下,将链表中的奇数和偶数索引节点重新排序的方法,并提供了相应的Python实现代码。
30 0
|
2月前
|
Python
【Leetcode刷题Python】25.K 个一组翻转链表
解决LeetCode "K 个一组翻转链表" 问题的三种方法:使用栈、尾插法和虚拟节点顺序法,并提供了每种方法的Python实现代码。
27 0
01_移除链表元素
01_移除链表元素
|
2月前
|
存储 算法
LeetCode第83题删除排序链表中的重复元素
文章介绍了LeetCode第83题"删除排序链表中的重复元素"的解法,使用双指针技术在原链表上原地删除重复元素,提供了一种时间和空间效率都较高的解决方案。
LeetCode第83题删除排序链表中的重复元素
|
2月前
|
Python
【Leetcode刷题Python】114. 二叉树展开为链表
LeetCode上114号问题"二叉树展开为链表"的Python实现,通过先序遍历二叉树并调整节点的左右指针,将二叉树转换为先序遍历顺序的单链表。
23 3
【Leetcode刷题Python】114. 二叉树展开为链表
|
2月前
|
存储 C语言
【数据结构】c语言链表的创建插入、删除、查询、元素翻倍
【数据结构】c语言链表的创建插入、删除、查询、元素翻倍
【数据结构】c语言链表的创建插入、删除、查询、元素翻倍
|
2月前
【刷题记录】链表的回文结构
【刷题记录】链表的回文结构
|
2月前
|
Python
【Leetcode刷题Python】剑指 Offer 22. 链表中倒数第k个节点
Leetcode题目"剑指 Offer 22. 链表中倒数第k个节点"的Python解决方案,使用双指针法找到并返回链表中倒数第k个节点。
42 5
|
2月前
|
Python
【Leetcode刷题Python】剑指 Offer 18. 删除链表的节点
Leetcode题目"剑指 Offer 18. 删除链表的节点"的Python解决方案,通过使用双指针法找到并删除链表中值为特定数值的节点,然后返回更新后的链表头节点。
33 4
|
2月前
|
存储 Python
【Leetcode刷题Python】23. 合并K个升序链表
合并K个升序链表的方法:使用数组排序的暴力求解法、使用小顶堆的高效方法,以及分而治之的策略,并提供了相应的Python实现代码。
15 1