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

佟年为韩商言做的网站2023年6月份又封城了

佟年为韩商言做的网站,2023年6月份又封城了,做网站测试需要学什么多,深圳网站开发公司有哪些Day109 | 灵神 | 148.排序链表 | 归并排序 148. 排序链表 - 力扣(LeetCode) 以下是灵神的题解,笔者认为这题只要可以看懂就好了 两种方法:分治和迭代 文章目录 Day109 | 灵神 | 148.排序链表 | 归并排序前置题目方法一&#x…

Day109 | 灵神 | 148.排序链表 | 归并排序

148. 排序链表 - 力扣(LeetCode)

以下是灵神的题解,笔者认为这题只要可以看懂就好了

两种方法:分治和迭代

文章目录

  • Day109 | 灵神 | 148.排序链表 | 归并排序
    • 前置题目
    • 方法一:归并排序(分治)
        • 复杂度分析
    • 方法二:归并排序(迭代)
        • 复杂度分析

前置题目

  • 876. 链表的中间结点
  • 21. 合并两个有序链表

方法一:归并排序(分治)

  1. 找到链表的中间结点 head2 的前一个节点,并断开 head2 与其前一个节点的连接。这样我们就把原链表均分成了两段更短的链表
  2. 分治,递归调用 sortList,分别排序 head(只有前一半)和 head2。
  3. 排序后,我们得到了两个有序链表,那么合并两个有序链表,得到排序后的链表,返回链表头节点。
class Solution {// 876. 链表的中间结点(快慢指针)ListNode* middleNode(ListNode* head) {ListNode* pre = head;ListNode* slow = head;ListNode* fast = head;while (fast && fast->next) {pre = slow; // 记录 slow 的前一个节点slow = slow->next;fast = fast->next->next;}pre->next = nullptr; // 断开 slow 的前一个节点和 slow 的连接return slow;}// 21. 合并两个有序链表(双指针)ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {ListNode dummy; // 用哨兵节点简化代码逻辑ListNode* cur = &dummy; // cur 指向新链表的末尾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->next = list1 ? list1 : list2; // 拼接剩余链表return dummy.next;}public:ListNode* sortList(ListNode* head) {// 如果链表为空或者只有一个节点,无需排序if (head == nullptr || head->next == nullptr) {return head;}// 找到中间节点 head2,并断开 head2 与其前一个节点的连接// 比如 head=[4,2,1,3],那么 middleNode 调用结束后 head=[4,2] head2=[1,3]ListNode* head2 = middleNode(head);// 分治head = sortList(head);head2 = sortList(head2);// 合并return mergeTwoLists(head, head2);}
};
复杂度分析
  • 时间复杂度:O(nlogn),其中 n 是链表长度。递归式 T(n)=2T(n/2)+O(n),由主定理可得时间复杂度为 O(nlogn)。
  • 空间复杂度:O(logn)。递归需要 O(logn) 的栈开销。

方法二:归并排序(迭代)

方法一的归并是自顶向下计算,需要 O(logn) 的递归栈开销。

方法二将其改成自底向上计算,空间复杂度优化成 O(1)。

自底向上的意思是:

  • 首先,归并长度为 1 的子链表。例如 [4,2,1,3],把第一个节点和第二个节点归并,第三个节点和第四个节点归并,得到 [2,4,1,3]。
  • 然后,归并长度为 2 的子链表。例如 [2,4,1,3],把前两个节点和后两个节点归并,得到 [1,2,3,4]。
  • 然后,归并长度为 4 的子链表。
  • 依此类推,直到归并的长度大于等于链表长度为止,此时链表已经是有序的了。

具体算法:

  1. 遍历链表,获取链表长度 length
  2. 初始化步长 step=1。
  3. 循环直到 steplength
  4. 每轮循环,从链表头节点开始。
  5. 分割出两段长为 step 的链表,合并,把合并后的链表插到新链表的末尾。重复该步骤,直到链表遍历完毕。
  6. step 扩大一倍。回到第 4 步。
class Solution {// 获取链表长度int getListLength(ListNode* head) {int length = 0;while (head) {length++;head = head->next;}return length;}// 分割链表// 如果链表长度 <= size,不做任何操作,返回空节点// 如果链表长度 > size,把链表的前 size 个节点分割出来(断开连接),并返回剩余链表的头节点ListNode* splitList(ListNode* head, int size) {// 先找到 next_head 的前一个节点ListNode* cur = head;for (int i = 0; i < size - 1 && cur; i++) {cur = cur->next;}// 如果链表长度 <= sizeif (cur == nullptr || cur->next == nullptr) {return nullptr; // 不做任何操作,返回空节点}ListNode* next_head = cur->next;cur->next = nullptr; // 断开 next_head 的前一个节点和 next_head 的连接return next_head;}// 21. 合并两个有序链表(双指针)// 返回合并后的链表的头节点和尾节点pair<ListNode*, ListNode*> mergeTwoLists(ListNode* list1, ListNode* list2) {ListNode dummy; // 用哨兵节点简化代码逻辑ListNode* cur = &dummy; // cur 指向新链表的末尾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->next = list1 ? list1 : list2; // 拼接剩余链表while (cur->next) {cur = cur->next;}// 循环结束后,cur 是合并后的链表的尾节点return {dummy.next, cur};}public:ListNode* sortList(ListNode* head) {int length = getListLength(head); // 获取链表长度ListNode dummy(0, head); // 用哨兵节点简化代码逻辑// step 为步长,即参与合并的链表长度for (int step = 1; step < length; step *= 2) {ListNode* new_list_tail = &dummy; // 新链表的末尾ListNode* cur = dummy.next; // 每轮循环的起始节点while (cur) {// 从 cur 开始,分割出两段长为 step 的链表,头节点分别为 head1 和 head2ListNode* head1 = cur;ListNode* head2 = splitList(head1, step);cur = splitList(head2, step); // 下一轮循环的起始节点// 合并两段长为 step 的链表auto [head, tail] = mergeTwoLists(head1, head2);// 合并后的头节点 head,插到 new_list_tail 的后面new_list_tail->next = head;new_list_tail = tail; // tail 现在是新链表的末尾}}return dummy.next;}
};
复杂度分析
  • 时间复杂度:O(nlogn),其中 n 是链表长度。
  • 空间复杂度:O(1)。
http://www.cadmedia.cn/news/2738.html

相关文章:

  • 人力招聘网站建设任务执行书搜索引擎优化英文简称
  • 网站推广运营招聘企业营销型网站
  • 旅游网站建设水平评价宁波seo公司排名榜
  • dedecms微电影网站模板今天的国内新闻
  • 内乡微网站建设怎么申请网站空间
  • 建设制作网站国外搜索引擎排行榜
  • 广东建设安全质量协会网站东莞营销网站建设
  • 翻译网站建设b站引流推广
  • 固始县住房和城乡建设局网站seocms
  • 企业设计网站公司有哪些怎么看app的下载网址
  • 网站建设流程seo标题优化分析范文
  • 大型餐饮网站建设网站域名注册
  • 德宏商城网站建设知识营销成功案例介绍
  • 网站建设国风网络公司厦门人才网唯一官网登录
  • 常州个人网站建设西安百度推广开户运营
  • 网站建设 生产百度小程序排名优化
  • 企业网盘怎么上传文件seo网络优化专员
  • 西安找公司建网站百度指数搜索指数的数据来源
  • 深圳模具外贸网站建设去哪里推广软件效果好
  • 佛山网络公司推荐承德seo
  • 金蝶软件中国有限公司百度seo关键词报价
  • 重庆网站建设套餐磁力猫最佳搜索引擎入口
  • 网站结算系统怎么做杭州网站建设 seo
  • 广东东莞天气预报15天整站优化外包服务
  • 学校网站建设项目的wbs安徽百度关键词优化
  • 免费html网页模板素材网站域名备案查询官网
  • 中国建筑网站平台有哪些企业为何选择网站推广外包?
  • 北京高端网站公司哪家好bt磁力搜索引擎在线
  • 网站设计制作公司推荐百度竞价排名推广
  • 百度关键词优化多少钱一年关键词首页排名优化平台