首页 > 编程语言 >算法打卡|Day4 链表part02

算法打卡|Day4 链表part02

时间:2023-09-24 16:56:00浏览次数:58  
标签:head ListNode part02 next 链表 打卡 newHead 节点

Day4 链表part02

今日任务
● 24. 两两交换链表中的节点
● 19.删除链表的倒数第N个节点
● 面试题 02.07. 链表相交
● 142.环形链表II


[TOC]

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

思路

1.迭代法就要注意画图!画图!还是画图!另外迭代的次序不要忘记,链表迭代统一从左往右迭代。用三个结点去一遍遍迭代
image.png
2.使用递归法,先交换前两个结点,然后指向递归好的链表就行。

解题方法

迭代或递归

Code


/**
时间复杂度:O(n)
空间复杂度:O(1)
*/
class Solution {
public:
  ListNode* swapPairs(ListNode* head) {
      auto dummy = new ListNode(0,head);
      ListNode* a = dummy;
      while (a->next != nullptr && a->next->next != nullptr){          

          ListNode* b = a->next;
          ListNode* c = a->next->next;
          a->next = c;
          b->next =c->next;
          c->next =b;
          a = b;
      }
      return dummy->next;
  }
  
};

Code


/**
时间复杂度:O(n)
空间复杂度:O(n)
拓展
*/

//思路:两两交换链表中的节点,拿第一个节点头节点head与第二个节点newHead(newHead = head.next) 来讲,需要将head与newHead交换位置,使newHead变成链表中的头节点,head变成第二个节点,然后head再指向已经处理好的链表,以此类推,递归调用本身,直到最后只剩下一个节点或者为空,结束返回新的头指针,也就是newHead
class Solution {
public:
  ListNode* swapPairs(ListNode* head) {
      //递归边界条件, 有2个结点才需要交换
      if(head == nullptr || head->next == nullptr){
          return head;
      }
      ListNode* newHead =head->next;
      head->next = swapPairs(newHead->next);
      newHead->next = head;
      return newHead;
  }
};

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

思路

首先我们要用快慢指针,快指针先走,慢指针再和快指针同步走。不过,要删除一个节点需要走到那个节点的前一个,所以我们要让快指针多走一个。比如要删除倒数第二个节点,我们就要让快指针先走3格。最后记得虚拟头结点,因为可能涉及到真实头结点的删除。
image.png

解题方法

双指针

Code


/**
时间复杂度: O(n)
空间复杂度: O(1)
*/
class Solution {
public:
  ListNode* removeNthFromEnd(ListNode* head, int n) {
      ListNode* dummyhead = new ListNode(0, head);
      ListNode* fast = dummyhead;
      ListNode* slow = dummyhead;
      n++;
      while(n-- && fast != nullptr){
          fast = fast->next;
      }

      while(fast!=nullptr){
          slow = slow->next;
          fast = fast->next;
      }

      slow->next = slow->next->next;

      //此处不能head,因为如果只有1个节点,应该返回空,而不是原来的hea(head发生了改变);并且slow改变的是虚拟节点后续的链表
      return dummyhead->next;

  }
};

Problem: 面试题 02.07. 链表相交

思路

如果有公共结点肯定是在后面重叠,且后面部分都是共同的。
方法1:先计算出两个链表的长度,可以让比较长的先走两个链表长度之差的步数,两个再一起走。
方法2:不同部分为a, 和b,公共部分为c;a + c + b = b + c + a;让两个一起走,a走到头就转向b, b走到头转向a,则在公共部分相遇。
image.png

解题方法

双指针法

复杂度

  • 时间复杂度:

\(O(2n)\)

  • 空间复杂度:

\(O(1)\)

Code


/**
* Definition for singly-linked list.
* struct ListNode {
*     int val;
*     ListNode *next;
*     ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
  ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
      ListNode *p1 = headA;
      ListNode *p2 = headB;

      while (p1 != p2) {
          if(p1 != NULL)//p1没有走到结尾
              p1 = p1->next;//p1指向下一个节点
          else//p1走到结尾
              p1 = headB;//p1指向另一个链表头
          if(p2 != NULL)//p2没有走到结尾
              p2 = p2->next;//p2指向下一个节点
          else  //p2走到结尾 
              p2 = headA;//p2指向另一个链表头
      }
      return p1;
      
  }
};

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

[TOC]

思路

1.迭代法就要注意画图!画图!还是画图!另外迭代的次序不要忘记,链表迭代统一从左往右迭代。用三个结点去一遍遍迭代
image.png
2.使用递归法,先交换前两个结点,然后指向递归好的链表就行。

解题方法

迭代或递归

Code


/**
时间复杂度:O(n)
空间复杂度:O(1)
*/
class Solution {
public:
  ListNode* swapPairs(ListNode* head) {
      auto dummy = new ListNode(0,head);
      ListNode* a = dummy;
      while (a->next != nullptr && a->next->next != nullptr){          

          ListNode* b = a->next;
          ListNode* c = a->next->next;
          a->next = c;
          b->next =c->next;
          c->next =b;
          a = b;
      }
      return dummy->next;
  }
  
};

Code


/**
时间复杂度:O(n)
空间复杂度:O(n)
拓展
*/

//思路:两两交换链表中的节点,拿第一个节点头节点head与第二个节点newHead(newHead = head.next) 来讲,需要将head与newHead交换位置,使newHead变成链表中的头节点,head变成第二个节点,然后head再指向已经处理好的链表,以此类推,递归调用本身,直到最后只剩下一个节点或者为空,结束返回新的头指针,也就是newHead
class Solution {
public:
  ListNode* swapPairs(ListNode* head) {
      //递归边界条件, 有2个结点才需要交换
      if(head == nullptr || head->next == nullptr){
          return head;
      }
      ListNode* newHead =head->next;
      head->next = swapPairs(newHead->next);
      newHead->next = head;
      return newHead;
  }
};

标签:head,ListNode,part02,next,链表,打卡,newHead,节点
From: https://www.cnblogs.com/RickRuan/p/17726194.html

相关文章

  • 力扣-链表组件
    1.问题给定链表头结点head,该链表上的每个结点都有一个唯一的整型值。同时给定列表G,该列表是上述链表中整型值的一个子集。返回列表G中组件的个数,这里对组件的定义为:链表中一段极长连续结点的值(该值必须在列表G中)构成的集合。极长的含义是:这段连续结点的前面或后面结点不......
  • 算法打卡|Day3 链表part01
    Day3链表part01今日任务●链表理论基础●203.移除链表元素●707.设计链表●206.反转链表[TOC]链表理论基础文章链接:https://programmercarl.com/%E9%93%BE%E8%A1%A8%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html重点:单链表是一种通过指针串联在一起的线性结构,每一......
  • Leetcode刷题21.合并两个有序链表
    将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。  示例1:输入:l1=[1,2,4],l2=[1,3,4]输出:[1,1,2,3,4,4]示例2:输入:l1=[],l2=[]输出:[]示例3:输入:l1=[],l2=[0]输出:[0] 提示:两个链表的节点数目......
  • 923打卡
    1.三数之和(15)给你一个整数数组 nums ,判断是否存在三元组 [nums[i],nums[j],nums[k]] 满足 i!=j、i!=k 且 j!=k ,同时还满足 nums[i]+nums[j]+nums[k]==0 。请你返回所有和为 0 且不重复的三元组。classSolution{publicList<List<Integer>>......
  • 随想录Day4|24. 两两交换链表中的节点、19. 删除链表的倒数第N个节点、面试题 02.07.
    随想录Day4|24.两两交换链表中的节点、19.删除链表的倒数第N个节点、面试题02.07.链表相交、142.环形链表Ⅱ 24.两两交换链表中的节点文章讲解视频讲解给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,......
  • 【算法】链表
    1链表理论基础链表是一种通过指针串联在一起的线性结构,每一个节点由两部分组成,一个是数据域一个是指针域(存放指向下一个节点的指针),最后一个节点的指针域指向null(空指针的意思)。链表的入口节点称为链表的头结点也就是head。链表中的节点在内存中不是连续分布的,而是散乱分布在内......
  • 数据结构之 - 链表数据结构详解: 从基础到实现
    链表(LinkedList)是计算机科学中常用的数据结构之一,它具有灵活的内存分配和高效的插入、删除操作。本文将深入介绍链表的特性、基本类型、操作以及在实际应用中的使用场景。1.什么是链表?链表是一种线性数据结构,由一系列节点组成,每个节点包含数据和指向下一个节点的引用(或指针)。与数......
  • 打卡
    9月22日:今天上午上了形势与政策课程,下午我们学习了高级英语,通过两节课的学习,我有从中学习了单词与语法,与此同时今天我也将java课的课后作业完成。明天做数据结构与算法的课后习题,然后抽时间学习一下java。......
  • 每日打卡 周五 九月二十二日
    今天又上英语课,快要四级考试了,得抓紧学习英语,下午完课后,看了一会儿英语单词,主要是翻译有问题,以前没有做过的题型也会一直是难,主要是想不词语的意思可以那样用。其实主要功课就是背单词,现在词汇积累的少,出现都不认识,在着就是听听力,真的是要很好的训练了。......
  • 922打卡
    1.盛最多水的容器(11)给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i,0) 和 (i,height[i]) 思想:双指针classSolution{publicintmaxArea(int[]height){intleft=0;intright=height.length-1;i......