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

240425 leetcode exercises

240425 leetcode exercises

@jarringslee

文章目录

  • 240425 leetcode exercises
    • [147. 对链表进行插入排序](https://leetcode.cn/problems/insertion-sort-list/)
      • 🔁插入排序
    • [1721. 交换链表中的节点](https://leetcode.cn/problems/swapping-nodes-in-a-linked-list/)
      • 🔁双指针

147. 对链表进行插入排序

给定单个链表的头 head ,使用 插入排序 对链表进行排序,并返回 排序后链表的头

插入排序 算法的步骤:

  1. 插入排序是迭代的,每次只移动一个元素,直到所有元素可以形成一个有序的输出列表。
  2. 每次迭代中,插入排序只从输入数据中移除一个待排序的元素,找到它在序列中适当的位置,并将其插入。
  3. 重复直到所有输入数据插入完为止。

下面是插入排序算法的一个图形示例。部分排序的列表(黑色)最初只包含列表中的第一个元素。每次迭代时,从输入数据中删除一个元素(红色),并就地插入已排序的列表中。

对链表进行插入排序。

img

示例 1:

img

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

示例 2:

img

输入: head = [-1,5,3,4,0]
输出: [-1,0,3,4,5]

🔁插入排序

在数组中,插入和移动元素可能涉及大量的数据移动,而在链表中,只需调整指针即可完成插入操作,因此插入排序在链表中更为高效。

我们将链表分为两个部分:已排序部分和未排序部分。初始时,已排序部分只包含链表的第一个节点,其余节点组成未排序部分。我们逐个从未排序部分取出节点,插入到已排序部分的正确位置,直到未排序部分为空。

为了简化插入操作,特别是在头部插入的情况,我们引入一个虚拟头节点。这个虚拟头节点的值可以设为任意值(如0),其next指针指向原链表的头节点。

struct ListNode *insertionSortList(struct ListNode *head) {if (head == NULL) return head;// 创建虚拟头节点struct ListNode *newHead = malloc(sizeof(struct ListNode));newHead->val = 0;newHead->next = head;struct ListNode *last = head;           // 已排序部分的最后一个节点struct ListNode *curr = head->next;     // 当前待插入的节点while (curr != NULL) {if (last->val <= curr->val) {// 当前节点已经在正确位置,无需移动last = last->next;} else {// 找到插入位置struct ListNode *prev = newHead;while (prev->next->val <= curr->val) {prev = prev->next;}// 插入当前节点到正确位置last->next = curr->next;curr->next = prev->next;prev->next = curr;}curr = last->next;}return newHead->next;
}
  • 插入排序在链表中实现相对简单,特别适用于小规模数据或部分有序的数据。
  • 通过引入虚拟头节点,可以简化插入操作,避免处理特殊情况。
  • 虽然时间复杂度较高,但在特定场景下,插入排序仍然是一个不错的选择。

1721. 交换链表中的节点

交换 链表正数第 k 个节点和倒数第 k 个节点的值后,返回链表的头节点(链表 从 1 开始索引)。

示例 1:

img

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

示例 2:

输入:head = [7,9,6,6,7,8,3,0,9,5], k = 5
输出:[7,9,6,6,8,7,3,0,9,5]

示例 3:

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

示例 4:

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

示例 5:

输入:head = [1,2,3], k = 2
输出:[1,2,3]

🔁双指针

首先我们定位整数第k个结点。使用一个指针 fast 从头开始,向前移动 k-1 次,fast 此时指向第 k 个节点,并将该节点保存为 tar1。继续使用 fast 指针向前移动,直到到达链表末尾。同时,使用另一个指针 tar2 从头开始来定位倒数第k个结点,每次 fast 向前移动时,tar2 也向前移动。当 fast 到达末尾时,tar2 指向的就是倒数第 k 个节点。

交换 tar1tar2val 值。

为什么使用 --k 而不是 k-- ???

使用 while (--k) 而不是 while (k--) 是为了确保指针 fast 向前移动 k-1 次,从而指向第 k 个节点。

  • --k 是前缀递减,表示在使用 k 之前先将其减 1。
  • k-- 是后缀递减,表示在使用 k 之后再将其减 1。

如果使用 k--,则循环会执行 k 次,fast 最终会指向第 k+1 个节点,导致错误。

struct ListNode* swapNodes(struct ListNode* head, int k) {struct ListNode *tar1, *tar2;struct ListNode *fast = head;tar2 = head;// 移动 fast 指针 k-1 次,fast 指向第 k 个节点while (--k) {fast = fast->next;}tar1 = fast;// 继续移动 fast 到链表末尾,同时移动 tar2while (fast->next) {fast = fast->next;tar2 = tar2->next;}// 交换 tar1 和 tar2 的值int temp = tar1->val;tar1->val = tar2->val;tar2->val = temp;return head;
}

相关文章:

  • 常见网络安全攻击类型深度剖析(一):恶意软件攻击——病毒、蠕虫、木马的原理与防范
  • promethus基础
  • 【C/C++】从源码到执行:程序运行的完整生命周期解析
  • 风车邮箱系统详细使用指南:Windows与Ubuntu双平台解析
  • 一键设置屏幕水印 助力数据安全
  • gophish
  • 机器学习基础 - 回归模型之线性回归
  • 同一电脑下使用 python2 和 python3
  • 使用开源免费雷池WAF防火墙,接入保护你的网站
  • 100个用户的聊天系统:轮询 vs WebSocket 综合对比
  • 重生之--js原生甘特图实现
  • WordPress AI插件能自动写高质量文章吗,如何用AI提升网站流量
  • Python 3.14:探索新版本的魅力与革新
  • 7.11 Python CLI开发实战:API集成与异步处理核心技术解析
  • 人工智能在创意设计中的应用:激发无限可能
  • 【高频考点精讲】JavaScript事件循环机制:从宏任务微任务到渲染时机
  • P12167 [蓝桥杯 2025 省 C/Python A] 倒水
  • Python Transformers 库介绍
  • 慧星云荣登杭州AI卧龙图
  • 未来乘用车电气/电子(E/E)架构与商用车电气/电子架构有何不同?
  • 商务部:已有超1.2亿人次享受到以旧换新补贴优惠
  • 最新研究挑战男性主导说:雌性倭黑猩猩联盟对付雄性攻击,获得主导地位
  • 人大法工委:涉核领域还需要有一部统领性的基础法律
  • 国家发改委:更大力度、更实举措促进民营经济高质量发展
  • 上海体育消费节将从5月持续至11月,推出运动装备商品促销活动
  • 韩国检方起诉前总统文在寅