【代码随想录】刷题笔记Day8

前言

现在下午1点半,奋战链表一下午!

206. 反转链表

  • 双指针法:设置一前一后pre和cur指针去修改链表的指针,掌握思路很重要
    • class Solution {
      public:
          ListNode* reverseList(ListNode* head) {
              ListNode* temp; // 保存cur的下一个节点
              ListNode* cur = head;
              ListNode* pre = NULL;
              while(cur) {
                  temp = cur->next;  // 保存一下 cur的下一个节点,因为接下来要改变cur->next
                  cur->next = pre; // 翻转操作
                  // 更新pre 和 cur指针
                  pre = cur;
                  cur = temp;
              }
              return pre;
          }
      };
  •  递归法:实际上还是根据双指针的思路来的
    • class Solution {
      public:
          ListNode* reverse(ListNode* pre,ListNode* cur){
              if(cur == NULL) return pre;
              ListNode* temp = cur->next;
              cur->next = pre;
              // 可以和双指针法的代码进行对比,如下递归的写法,其实就是做了这两步
              // pre = cur;
              // cur = temp;
              return reverse(cur,temp);
          }
          ListNode* reverseList(ListNode* head) {
              // 和双指针法初始化是一样的逻辑
              // ListNode* cur = head;
              // ListNode* pre = NULL;
              return reverse(NULL, head);  // 传参初始化
          }
      
      };
  • 其他解法:虚拟头节点+头插法、以后有机会再写好了 

24. 两两交换链表中的节点

  • 这题画图模拟更加清晰,注意连新的就删旧的,用虚拟头节点比较方便
  • 【代码随想录】刷题笔记Day8_第1张图片
  • class Solution {
    public:
        ListNode* swapPairs(ListNode* head) {
            ListNode* dummyHead = new ListNode(0);  // 设置一个虚拟头结点
            dummyHead->next = head;  // 将虚拟头结点指向head,这样方面后面做删除操作
            ListNode* cur = dummyHead;
            while(cur->next != nullptr && cur->next->next != nullptr){
                ListNode* temp1 = cur->next;  // 记录临时节点
                ListNode* temp2 = cur->next->next->next;  // 记录临时节点
    
                cur->next = temp1->next;  // 步骤一
                cur->next->next = temp1;  // 步骤二
                temp1->next = temp2;  // 步骤三
    
                cur = cur->next->next;  // cur移动两位,准备下一轮交换
            }
            return dummyHead->next;  // 注意不是返回head
        }
    };

 19. 删除链表的倒数第 N 个结点

  • 双指针法即可实现,同样用虚拟头节点(以后都默认了)
  • 【代码随想录】刷题笔记Day8_第2张图片
  • class Solution {
    public:
        ListNode* removeNthFromEnd(ListNode* head, int n) {
            ListNode* dummyHead = new ListNode(0);
            dummyHead->next = head;
            ListNode* fast = dummyHead;
            ListNode* slow = dummyHead;
            n = n + 1;  // fast先走n+1步
            while(n -- && fast != nullptr){
              fast = fast->next;  
            }
            while(fast != nullptr){
              slow = slow->next;
              fast = fast->next;  // fast走到底
            }
            slow->next = slow->next->next;  // 删除slow的下一个结点
            return dummyHead->next;
        }
    };

 面试题 02.07. 链表相交

  • 题目描述真的愣是看不懂,原来是求指针交叉的指针啊。。。
  • 代码随想录的方法是用双指针求长度之后右对齐再比较是否一样
  • 【代码随想录】刷题笔记Day8_第3张图片
  • 但是如果相交后后面一定是一样的,有另一种解法双指针法,巨简洁!!直呼NB
  • class Solution {
    public:
        ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
            ListNode* curA = headA;  // 前提是相交后后面一定是一样的
            ListNode* curB = headB;
            while(curA != curB){  // 只要不相交就一起走
                curA = (curA == NULL? headB:curA->next);
                curB = (curB == NULL? headA:curB->next);  // 谁走完就跳到对面继续走
            }
            return curA;  // 返回相等处的指针/空指针
        }
    };

 后言

今天的代码就刷到这里!链表还挺好玩的哈哈哈,指针指来指去的。和女朋友撸串去咯!

你可能感兴趣的:(代码随想录刷题笔记,链表,数据结构,算法,leetcode,职场和发展)