当前位置: 首页 > news >正文

240419 leetcode exercises

240419 leetcode exercises

@jarringslee

文章目录

  • 240419 leetcode exercises
    • [19. 删除链表的倒数第 N 个结点](https://leetcode.cn/problems/remove-nth-node-from-end-of-list/)
      • 🔁 经典方法:两次遍历暴力求解
      • 🔁 双指针法 :快慢指针降低空间复杂度
    • [21. 合并两个有序链表](https://leetcode.cn/problems/merge-two-sorted-lists/)
      • 🔁 方法一:迭代法
      • 🔁 方法二:递归法: 利用函数栈自动拼接链表

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

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。

示例 1:

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

示例 2:

输入:head = [1], n = 1
输出:[]

示例 3:

输入:head = [1,2], n = 1
输出:[1]

🔁 经典方法:两次遍历暴力求解

​ 我们需要通过第一次遍历获取整个链表的长度L,再通过第二次遍历找到倒数第n个结点的位置,即整数第L - n + 1个结点并进行删除操作——从头开始走 length - n 步,找到要删除节点的“前一个节点”,让这个“前一个节点”的 next 指向要删节点的下一个节点。最后我们返回链表头即可。

//求链表长度的步骤可用函数单独封装
int getlenth(struct ListNode* head){int len = 0;while (head != NULL){len++;head = head -> next;//第一次遍历直到结点指针指向空}return len;
}struct ListNode* removeNthFromEnd(struct ListNode* head, int n) {struct ListNode* zhizhen = malloc(sizeof(struct ListNode));
//设置虚拟头结点并进行内存分配以便后续使用zhizhen -> val = 0;//虚拟节点不需要用到val值,直接设置为0即可zhizhen -> next = head;//虚拟头结点指向真正的头结点int len = getlenth(head);struct ListNode* now = zhizhen;//用指针开始第二次遍历for (int i = 1; i < len - n + 1; i++){now = now -> next;//因为第len - n + 1个结点是需要删除的结点,所以我们让虚拟头结点指向它的前一个结点}
//前后指针连接,删除指定结点now -> next = now -> next -> next;struct ListNode* cjx = zhizhen -> next;//用cjx暂存新的头结点(zhizhen->next)free(zhizhen);return cjx; // \释放zhizhen避免内存泄漏,并返回新头节点。
}

🔁 双指针法 :快慢指针降低空间复杂度

​ 我们已经通过反向思考知道了倒数第n个结点就是整数第L - n + 1个结点,那么我们如何利用这个发现来在不需要提前知道整个链表的情况下完成查找呢?可以利用快慢指针来进行差值查找。

​ 我们用快指针和慢指针同时对链表进行遍历。快指针先出发,直到遍历到第n个结点的时候慢指针以同样的速度出发,这样快慢指针之间永远间隔了n−1个节点,即超前了n个节点。

​ 当块指针走到尽头时,慢指针刚好指向第L - n 个结点,即倒数第n个结点的前一个结点。利用慢指针即可进行删除操作。

struct ListNode* removeNthFromEnd(struct ListNode* head, int n) {struct ListNode* zhizhen = malloc(sizeof(struct ListNode));zhizhen -> val = 0, zhizhen- > next = head;//插入快慢指针struct ListNode* first = head;struct ListNode* second = zhizhen;//快指针先走n个结点for (int i = 0; i < n; ++i) {first = first->next;}//随后慢指针出发 巧妙利用差值找到需要删除的结点的前一个结点while (first) {first = first->next;second = second->next;}second -> next = second -> next -> next;struct ListNode* cjx = zhizhen -> next;free(zhizhen);return cjx;
}

21. 合并两个有序链表

将两个升序链表合并为一个新的升序链表并返回。新链表由给定两个链表的所有节点拼接而成。

示例 1:

l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]

示例 2:

l1 = [], l2 = []
输出:[]

示例 3:

l1 = [], l2 = [0]
输出:[0]

🔁 方法一:迭代法

​ 我们设置一个dummy 来作为新链表的“起点”,并使用一个指针 cur 来记录当前新链表的末尾。每一步我们都比较两个链表当前节点的值,较小的接入新链表,然后对应链表向后移动一格。

​ 遍历结束后,剩余链表(必定是有序的)可以直接接到新链表末尾。

struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {struct ListNode dummy = {}; // 创建节点,val无所谓struct ListNode* cur = &dummy; // cur为新链表的移动指针,初始指向dummy// 同时遍历两个链表,每次接入较小值while (list1 && list2) {if (list1->val < list2->val) {cur->next = list1; // list1更小,接入新链表list1 = list1->next;} else {cur->next = list2; // list2更小或相等,接入新链表list2 = list2->next;}cur = cur->next; // 移动cur指针}// 拼接剩余部分(只会有一个链表剩下)cur->next = list1 ? list1 : list2;return dummy.next; // 返回新链表的头结点(dummy->next)
}
  • 设置一个虚拟头节点 dummy 可以省去处理头节点的特殊情况;
  • 通过 cur 指针不断拼接较小的节点;
  • 最后直接接上剩余链表即可,整个过程是原地修改,不创建额外节点,效率高。

🔁 方法二:递归法: 利用函数栈自动拼接链表

​ 本质思想仍然是“谁小谁先接”,通过递归不断比较当前两个链表的头结点值,较小的那个继续和另一个链表递归合并,直到某个链表为空,返回另一个链表作为终点。

struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {// 递归终止条件:有一个链表为空if (list1 == NULL) return list2;if (list2 == NULL) return list1;// 递归过程:谁小谁接到前面,并将它的next递归合并if (list1->val < list2->val) {list1->next = mergeTwoLists(list1->next, list2);return list1;} else {list2->next = mergeTwoLists(list1, list2->next);return list2;}
}```

相关文章:

  • 2025年最新版 Git和Github的绑定方法,以及通过Git提交文件至Github的具体流程(详细版)
  • DAY 49 leetcode 20--栈和队列.有效的括号
  • C++中动态多态类别浅析
  • C++之虚函数 Virtual Function
  • Matlab画海洋与大气变量的时间序列并带标记面的三维折线图--来源粉丝
  • 如何对docker镜像存在的gosu安全漏洞进行修复——筑梦之路
  • Macvlan 网络类型详解:特点、优势与局限性
  • C++入门七式——模板初阶
  • Nacos启动报错
  • 软件测试行业核心知识点的系统化梳理
  • 使用 TensorFlow 和 Keras 构建 U-Net
  • Python语法系列博客 · 第9期[特殊字符] 函数参数进阶:*args、**kwargs 与参数解包技巧
  • 混合精度训练中的算力浪费分析:FP16/FP8/BF16的隐藏成本
  • 深度学习--mnist数据集实现卷积神经网络的手写数字识别
  • 探索大语言模型(LLM):Transformer 与 BERT从原理到实践
  • 【OpenGL】OpenGL学习笔记-1:VS2019配置OpenGL开发环境
  • PR第一课
  • Arduino项目中硬件包括哪些部分
  • 【MATLAB海洋专题】历史汇总
  • 链表面试题
  • “你是做什么的?”——人们能否对工作说不?
  • “中国电三之都”江苏丰县成功举办第十五届电动车展览会
  • 报告:去年物业服务百强企业营业收入均值同比增长3.52%
  • 第八届进博会倒计时200天,超100家展商将连续八届参展
  • 重庆警方通报“货车轮胎滚进服务区致人死亡”:正进一步调查
  • 42岁北京大学科学技术与医学史系副教授陈昊逝世