• 链表OJ题(1)


    今天讲解两道链表OJ题目。

    1.链表的中间节点 

    给你单链表的头结点 head ,请你找出并返回链表的中间结点。

    如果有两个中间结点,则返回第二个中间结点。

    示例 

     

    输入:head = [1,2,3,4,5]
    输出:[3,4,5]
    解释:链表只有一个中间结点,值为 3 

    方法1【 双指针】

    时间复杂度O(N)

    思想:两个指针,faster的速度是slow两倍,则当faster走到结尾时,slow则走到链表中间。

    易错:循环条件 

    1. /**
    2. * Definition for singly-linked list.
    3. * struct ListNode {
    4. * int val;
    5. * struct ListNode *next;
    6. * };
    7. */
    8. struct ListNode* middleNode(struct ListNode* head)
    9. {
    10. struct ListNode*faster=head;
    11. struct ListNode*slow=head;
    12. while(faster && faster->next)//条件没想到
    13. {
    14. faster=faster->next->next;
    15. slow=slow->next;
    16. }
    17. return slow;
    18. }

    2.移除链表元素

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

    示例 

    输入:head = [1,2,6,3,4,5,6], val = 6
    输出:[1,2,3,4,5]
    

    方法1【三指针--无哨兵位】

    时间复杂度:O(N)

    思想:三个指正,cur负责对比val,tmp负责存储删除元素的下一个元素地址,prve负责存储删除元素的上一个元素地址

    易错:

    • 记住prve是cur的前一个元素,那么它从NULL开始
    • 循环条件
    • 记得处理头节点和尾节点
    • 造成野指针的错误❌

    1. /**
    2. * Definition for singly-linked list.
    3. * struct ListNode {
    4. * int val;
    5. * struct ListNode *next;
    6. * };
    7. */
    8. struct ListNode* removeElements(struct ListNode* head, int val)
    9. {
    10. struct ListNode*cur=head;
    11. struct ListNode*prve=NULL;
    12. while(cur)
    13. {
    14. if(cur->val == val)
    15. {
    16. struct ListNode*tmp=cur->next;
    17. free(cur);
    18. if(prve)
    19. {
    20. prve->next=tmp;
    21. }
    22. else
    23. {
    24. head=tmp;
    25. }
    26. cur=tmp;
    27. }
    28. else
    29. {
    30. prve=cur;
    31. cur=cur->next;
    32. }
    33. }
    34. return head;
    35. }

    方法2【双指针---无哨兵位】

    1. /**
    2. * Definition for singly-linked list.
    3. * struct ListNode {
    4. * int val;
    5. * struct ListNode *next;
    6. * };
    7. */
    8. struct ListNode* removeElements(struct ListNode* head, int val)
    9. {
    10. struct ListNode*newhead=NULL;
    11. struct ListNode*tail=NULL;
    12. struct ListNode*cur=head;
    13. while(cur)
    14. {
    15. if(cur->val != val)
    16. {
    17. if(newhead == NULL)
    18. {
    19. newhead=tail=cur;
    20. }
    21. else
    22. {
    23. tail->next=cur;
    24. tail=tail->next;
    25. }
    26. cur=cur->next;
    27. }
    28. else
    29. {
    30. struct ListNode*tmp=cur->next;
    31. free(cur);
    32. cur=tmp;
    33. }
    34. if(tail)
    35. {
    36. tail->next=NULL;
    37. }
    38. }
    39. return newhead;
    40. }
    41. //❌改进

    那有哨兵位怎么写呢?

    当然,这道题还可以联系前面顺序表(移除val)。

    代码---------→【唐棣棣 (TSQXG) - Gitee.com

    联系---------→【邮箱:2784139418@qq.com】

  • 相关阅读:
    Chromium127调试指南 Windows篇 - 安装C++扩展与配置(五)
    电脑里重要文件用什么备份,电脑如何备份主要数据
    信息论随笔(二)信息熵及其性质
    IDEA版SSM入门到实战(Maven+MyBatis+Spring+SpringMVC) -Maven使用前准备
    day09渗透简单测试流程以及PKI实验
    倍增、DFS序
    【JVM学习03】类加载与字节码技术
    深入理解Windows系统环境变量
    SHA-256 简介及 C# 和 js 实现【加密知多少系列】
    3.1 首页功能的开发-跳转到首页
  • 原文地址:https://blog.csdn.net/m0_74841364/article/details/134228048