• 算法训练营第三天 | 203.移除链表元素、707.设计链表 、206.反转链表


    关于链表我们应该了解什么:

    代码随想录

    在实际开发中,遇到指针我们要做好防御性编程。


    问题( 一 )

    题目描述 :

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

    题目链接:

    203. 移除链表元素 - 力扣(LeetCode)


    问题分析:

              这到题目算是链表的基础操作 , 我这里写的是链表的前面是一个虚拟头节点,这样我们就不用考虑删除元素是否是头节点这个情况了 。主要掌握虚拟头节点,当然可以不用这个方法,但是这样会时链表的操作变得更加简洁。  删除的核心操作就是,找到要删除节点的前一个节点:他的next 就是我们要删除的节点    如果删除的节点的前一个节点是p,   那么 p->next = p->next->next。

    视频讲解:

    手把手带你学会操作链表 | LeetCode:203.移除链表元素_哔哩哔哩_bilibili


    解决方案:

    1. ListNode* removeElements(ListNode* head, int val) {
    2. ListNode *virtualNode =new ListNode; //定义一个虚拟头结点
    3. virtualNode->next=head;
    4. ListNode *temp=virtualNode;
    5. //遍历链表
    6. while( temp!= NULL && temp->next!=NULL){
    7. if(temp->next->val==val){ //找到了满足条件的节点
    8. //删除节点
    9. head=temp->next;
    10. temp->next=temp->next->next;
    11. delete head;
    12. continue;
    13. }
    14. temp=temp->next;
    15. }
    16. return virtualNode->next;
    17. }

    问题( 二  )

    题目描述 :

    设计链表,可以是单链表也可以是双链表。

    题目链接:

    707. 设计链表 - 力扣(LeetCode)

    问题分析:

            我自己给出的答案是单链表的设计 , 包括一些基础操作,增删查。我们需要知道的是链表也是从0开始计数的,删除和在指定位置插入,我们都是找到待操作位置的前一个位置。

    视频讲解:

    帮你把链表操作学个通透!LeetCode:707.设计链表_哔哩哔哩_bilibili

    解决方案:

    1. class MyLinkedList { //才用虚拟头节点法
    2. public:
    3. MyLinkedList() {
    4. head = new ListHead;
    5. head->next = NULL;
    6. head->val = 0;
    7. size = 0;
    8. }
    9. //获取元素
    10. int get(int index) {
    11. //防御性编程
    12. if (!head ) return -1; //链表不存在,或者为空
    13. if (head->next == NULL) return -1;
    14. if (index < 0) return -1; //下标不合法
    15. if (index >= size) return -1;
    16. int i = 0;
    17. ListNode* p = head; //指向虚拟头结点
    18. while (i <=index) {
    19. p = p->next;
    20. i++;
    21. }
    22. return p->val;
    23. }
    24. //头部添加
    25. void addAtHead(int val) {
    26. if (!head) return;
    27. ListNode* node = new ListNode; //生成一个节点
    28. node->val = val;
    29. node->next = head->next;
    30. head->next = node;
    31. size++;
    32. }
    33. //尾部添加
    34. void addAtTail(int val) {
    35. if (!head) return; //判断链表是否存在
    36. ListNode* node = new ListNode; //生成一个节点
    37. node->val = val;
    38. ListNode* p = head; //指向第一个节点
    39. while (p->next!=NULL) {
    40. p = p->next;
    41. }
    42. //循环结束后说明刚好处于最后一个位置
    43. node->next = p->next;
    44. p->next = node;
    45. size++;
    46. }
    47. //在指定位置添加
    48. void addAtIndex(int index, int val) {
    49. if (!head) return; //链表不存在
    50. if (index < 0) return; //位置不合法
    51. if (index > size) return;
    52. ListNode* p = head; //指向虚拟头结点
    53. while ( index--) {
    54. p = p->next;
    55. }
    56. ListNode* node = new ListNode; //生成一个节点
    57. node->val = val;
    58. node->next = p->next;
    59. p->next = node;
    60. size++;
    61. }
    62. //删除位置的元素
    63. void deleteAtIndex(int index) {
    64. if (!head ) return;
    65. if (head->next == NULL) return; //没有元素
    66. if (index < 0) return ; //下标不合法
    67. if (index >= size) return ;
    68. LinkList* p = head;
    69. if (index == 0) {
    70. head->next = head->next->next;
    71. size--;
    72. return;
    73. }
    74. while ( index-- ) {
    75. p = p->next;
    76. }
    77. cout << p->val << endl;
    78. LinkList* temp = p->next;
    79. p->next = p->next->next;
    80. delete temp;
    81. size--;
    82. }
    83. void print() {
    84. ListNode* node = head->next;
    85. while (node) {
    86. cout << node->val << " ";
    87. node = node->next;
    88. }
    89. cout << endl;
    90. }
    91. private:
    92. //节点结构
    93. typedef struct LinkList {
    94. struct LinkList* next;
    95. int val;
    96. }ListHead,ListNode;
    97. ListHead* head;
    98. int size; //链表的长度
    99. };

    问题(  三  ) 

    题目描述 :给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

    题目链接:

    206. 反转链表 - 力扣(LeetCode)

    问题分析:

            这到题目,我们采用双指针的思路。指针 pro 用来记录我们head的前一个节点,开始没有翻转之前,head的前一个节点为NULL ,所有pro初始值为NULL,而我们的第二个指针 temp 则用来记录head的下一个节点。

     循环遍历我们的链表,终止条件是  head 指针为空,1-》2断开之后,1-》的next指向了 NULL,然后我们的  temp继续往后移动,而我们的 pro 则指向 head。

    视频加文字讲解:

     解决方案:

    1. ListNode* reverseList(ListNode* head) {
    2. if(!head) return NULL; //链表为空
    3. if(head->next==NULL) return head; //只有一个元素的情况
    4. ListNode *pro=NULL ; //用来只想当前位置的前一个节点
    5. ListNode *temp=head ;
    6. while( head ){
    7. temp = temp->next;
    8. head->next=pro;
    9. pro=head;
    10. head=temp;
    11. }
    12. head=pro;
    13. return head;
    14. }

  • 相关阅读:
    QChartView显示实时更新的温度曲线图,即动态曲线图。
    网络层详解
    OLED透明屏在智慧零售场景的应用
    如何玩转盲盒商城小程序玩法
    105. 从前序与中序遍历序列构造二叉树(中等 二叉树 dfs 哈希表 二叉树)
    CleanMyMac X4.11.2免费版专业的Mac电脑清理软件
    【Pytorch安装】windows下,安装了torch但是import torch失败
    Spark基础【运行架构、RDD】
    日常学习记录随笔-zabix实战
    UE4贴图自适应屏幕大小
  • 原文地址:https://blog.csdn.net/qq_62989250/article/details/134083387