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

单链表的排序

单链表的排序_牛客题霸_牛客网 (nowcoder.com)

这题主要的难点是链表只能按顺序访问,无法通过下标进行排序。

方法2:既然我们无法通过下标进行访问,那我们就将链表转成数组进行排序,数组排序有sort方法,不需要我们手动实现。

方法1:我们还可以将这个n个节点的单链表分成含n个一个节点的链表, 再将这n个单链表合并成一个有序链表。这个方法就是分治思想,分治算法通常是递归实现的;

方法1:分治法

public ListNode merge(ListNode h1, ListNode h2) {ListNode vhead = new ListNode(-1);ListNode cur = vhead;while (h1 != null && h2 != null) {if (h1.val < h2.val) {cur.next = h1;h1 = h1.next;} else {cur.next = h2;h2 = h2.next;}cur = cur.next;}if (h1 != null) {cur.next = h1;} else {cur.next = h2;}return vhead.next;
}
//方法1:单链表通过分治思想进行排序,分治的过程通过递归实现的
public ListNode sortInList (ListNode head) {// write code hereif (head == null || head.next == null){return head;//当链表为空或者只有一个元素时,此时的链表时有序的}ListNode slow = head;//慢指针指向头结点ListNode fast = head.next;//快指针在头结点的下一个节点,这样可以的话如果链表的长度为偶数个就可以指向中间节点的左边而不是右边while (fast != null && fast.next != null){slow = slow.next;fast = fast.next.next;}ListNode head2 = slow.next;//记录右半边链表的头结点slow.next = null;//将左右两边链表断开return merge(sortInList(head),sortInList(head2));//将左右两边链表合并成一个有序链表
}

同样使用分治思想的链表题:合并k个已排序的链表_牛客题霸_牛客网 (nowcoder.com) 

这题也同样使用分治思想,不用的是它可以通过下标查询链表的头结点,所以可以使用二分查找;还可以通过建立小根堆(lamdba表达式)的方式,每出一个节点就放进该节点的下一个节点。 

方法2:借助数组 --》改进(使用ArrayList进行存储)

//方法2.通过数组排序的方法对单链表进行排序
public int length(ListNode head){int count = 0;while (head != null){count++;head = head.next;}return count;
}
public ListNode sortInList (ListNode head) {// write code hereint len = length(head);//计算链表长度ListNode cur = head;int[] arr = new int[len];//创建一个相同长度的数组用于存储链表中的数据for (int i = 0; i < len; i++){arr[i] = cur.val;cur = cur.next;}Arrays.sort(arr);//对数组进行排序ListNode vhead = new ListNode(-1);//创建虚拟头结点cur = vhead;for(int i = 0; i < len; i++){cur.next = new ListNode(arr[i]);//创建新结点用于存放排序完数组中的数据cur = cur.next;}return vhead.next;
}//方法2的改进:使用顺序表ArrayList 存储数据
public ListNode sortInList (ListNode head) {// write code hereArrayList<Integer> nums = new ArrayList<>();ListNode cur = head;while (cur != null){nums.add(cur.val);cur = cur.next;}Collections.sort(nums);cur = head;for (int i = 0; i < nums.size(); i++){cur.val = nums.get(i);cur = cur.next;}return head;
}
http://www.xdnf.cn/news/8712.html

相关文章:

  • Collection集合遍历的三种方法
  • multiprocessing多进程使用案例
  • 用神经网络对信贷项目进行预测
  • java三种常见设计模式,工厂、策略、责任链
  • 原生php单元测试
  • bun全栈开发尝鲜:用bun-react-template实现Markdown文章展示
  • removeIf() 方法,结合 Lambda 表达式
  • 鸿蒙仓颉开发语言实战教程:页面跳转和传参
  • WORD 转 PDF 工具:排版 / 图片 / 表格批量转换提升办公效率
  • Acrobat 中 JavaScript 为 PDF 带来的交互
  • 篇章二 数据结构——前置知识(二)
  • C# 正则表达式
  • c/c++的opencv伽马噪声
  • ArrayList 与 LinkedList 区别?
  • 【c++11】智能指针 -- 摆脱内存困扰,现代编程的智能选择
  • OSCP备战-mr-robot靶机详细解法
  • conda 环境中opencv 报错
  • Maven Profile高级策略与冲突解决
  • 手眼标定:九点标定、十二点标定、OpenCV 手眼标定
  • Cursor最新问题不能使用Claude3.7问题的解决方案
  • [Linux]如何配置mailutils郵件服務?
  • 基于STM32的电容电阻测量仪Proteus仿真设计+程序设计+设计报告+讲解视频
  • MyBatis实战指南(三)MyBatis常用配置详解(XML配置,环境配置,类型别名,属性与映射器)
  • 【监控】Prometheus+Grafana 构建可视化监控
  • JVM 的垃圾回收器
  • 每日算法刷题计划Day15 5.25:leetcode不定长滑动窗口求子数组个数越短越合法3道题,用时1h
  • BUUCTF——RCE ME
  • 【数据结构】实现方式、应用场景与优缺点的系统总结
  • CAN通信收发测试(USB2CAN模块测试实验)
  • RocketMq的消息类型及代码案例