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

【算法】day13 链表

1、合并 K 个升序链表 hot

题目:23. 合并 K 个升序链表 - 力扣(LeetCode)

分析

(假设所有链表长度为 n,有 k 个链表)

法一,暴力解法:回想两个有序游标合并,合并一次时间复杂度 O(2n)=O(n)。那么第一个链表与后续的 k-1 个链表合并,需要遍历第一个链表 (k-1)n 次节点。那么 k 个链表合并,需要遍历 (k-1)n + (k-2)n + …… + 2n + n = n*k(k-1)/2 = O(n*k^2),相当于 O(n^3) 时间复杂度很高。

法二,优先队列(堆):每次把 k 个链表的头结点取出来比较,将最小的放入新链表,并将其遍历指针往后移,时间复杂度就是所有链表的长度和 O(kn)。但我们还需要获得 k 个节点中哪个最小,就可以用到大小为 k 的小根堆,每次取出堆顶的元素插入新链表然后往后移动,移动到的节点再插入堆,直到堆为空。因为堆中有 k 个节点,所以构建堆 O(klogk),后续假设每个节点插入、删除堆 O(kn*2logk),总时间复杂度:O(n*klogk)。空间复杂度,堆大小:O(k)。

法三,分治(递归):类似于归并排序,把数字元素替换为链表元素,然后我们合并的不是左右子数组,而是左右链表。因为有 k 个节点(链表),所以树高 logk,每层最多需要遍历 kn 个节点,时间复杂度:O(n*klogk)。空间复杂度,递归深度:O(logk)。

代码

优先队列:

/*** Definition for singly-linked list.* public class ListNode {*     int val;*     ListNode next;*     ListNode() {}*     ListNode(int val) { this.val = val; }*     ListNode(int val, ListNode next) { this.val = val; this.next = next; }* }*/
class Solution {public ListNode mergeKLists(ListNode[] lists) {// 1. 构建小根堆,把所有头结点插入堆PriorityQueue<ListNode> heap = new PriorityQueue<>((node1, node2) -> node1.val-node2.val);for (ListNode list : lists)if (list != null) heap.offer(list);// 2. 只要堆不为空,就取出堆顶尾插入新链表,并将指针后移ListNode newList = new ListNode();ListNode tail = newList;while (!heap.isEmpty()) {ListNode min = heap.poll();tail.next = min;tail = min;if (min.next != null) heap.offer(min.next);}return newList.next;}
}

递归:

/*** Definition for singly-linked list.* public class ListNode {*     int val;*     ListNode next;*     ListNode() {}*     ListNode(int val) { this.val = val; }*     ListNode(int val, ListNode next) { this.val = val; this.next = next; }* }*/
class Solution {public ListNode mergeKLists(ListNode[] lists) {return mergeLists(lists, 0, lists.length-1);}public ListNode mergeLists(ListNode[] lists, int l, int r) {// 递归结束条件if (l > r) return null;if (l == r) return lists[l];// 划分左右链表子数组,递归合并int mid = l+(r-l)/2;ListNode list1 = mergeLists(lists, l, mid);ListNode list2 = mergeLists(lists, mid+1, r);// 合并左右链表return mergeTwoLists(list1, list2);}public ListNode mergeTwoLists(ListNode list1, ListNode list2) {ListNode newHead = new ListNode();ListNode tail = newHead;while (list1 != null && list2 != null) {if (list1.val <= list2.val) {tail.next = list1;list1 = list1.next;} else {tail.next = list2;list2 = list2.next;}tail = tail.next;}if (list1 != null) tail.next = list1;if (list2 != null) tail.next = list2;return newHead.next;}
}

2、K 个一组翻转链表 hot

题目:25. K 个一组翻转链表 - 力扣(LeetCode)

分析:翻转链表,可以想到遍历链表节点,头插到新链表。我们可以分成 length/k 组进行翻转头插,最后 n%k 个不管。每组从 tmp 位置(上一组遍历的第一个节点)开始头插。时间复杂度 O(n),空间:O(1)。

代码

/*** Definition for singly-linked list.* public class ListNode {*     int val;*     ListNode next;*     ListNode() {}*     ListNode(int val) { this.val = val; }*     ListNode(int val, ListNode next) { this.val = val; this.next = next; }* }*/
class Solution {public ListNode reverseKGroup(ListNode head, int k) {// 1. 求链表长度int n = 0;ListNode t = head;while (t != null) {n++;t = t.next;}// 2. 划分成 n/k 组,每组遍历 k 个节点int m = n/k;ListNode cur = head;ListNode newHead = new ListNode(), tail = newHead;for (int i = 0; i < m; i++) {ListNode tmp = cur;for (int j = 0; j < k; j++) {// 执行头插ListNode next = cur.next;cur.next = tail.next;tail.next = cur;// 遍历到下一个节点cur = next;}// 下一组,从 tmp 节点开始头插tail = tmp;}// 3. 把剩下凑不够 k 个的节点,直接插到末尾tail.next = cur;return newHead.next;}
}

3、反转链表 hot

题目:206. 反转链表 - 力扣(LeetCode)

分析:上一个题都会做了,这个还不会?就是头插。时间复杂度 O(n),空间 O(1)。

代码

/*** Definition for singly-linked list.* public class ListNode {*     int val;*     ListNode next;*     ListNode() {}*     ListNode(int val) { this.val = val; }*     ListNode(int val, ListNode next) { this.val = val; this.next = next; }* }*/
class Solution {public ListNode reverseList(ListNode head) {if (head == null || head.next == null) return head;// 遍历,头插到新链表ListNode newHead = new ListNode();while (head != null) {ListNode next = head.next;head.next = newHead.next;newHead.next = head;head = next;}return newHead.next;}
}
http://www.dtcms.com/a/537959.html

相关文章:

  • 可以做网站的语言济南泰安网站建设公司
  • 超级工程网站建设上海中心大厦wordpress 登陆后台
  • 淮安网站定制wordpress多用户图库
  • 顺企网萍乡网站建设网站排名优化怎么弄
  • switch宝可梦传说Z-A金手指1.0.1免通信进化和持物通信进化修改
  • 校园电子商务网站建设网站制作教程网站
  • 长沙第三方网站建设公司辽宁工程建设信息网诚信库怎么填
  • 建网站需要什么软件义乌跨境电商公司前十名
  • 网站建设费 科目百度推广怎么注册账号
  • FP8013降压恒流单芯片切五路调光调色方案
  • 知识就是力量——数据库
  • 住建设部官方网站wordpress 4.7.2 中文
  • 当神谕落入都市老城区的染缸
  • PillarsOfModernCpp 报告总结
  • 网站建设这块是怎么挣钱手机版网站做一下多少钱
  • 凡科做的网站如何绑定域名移动网站建设哪家快
  • 【编译原理笔记】3.3 Specification of Tokens
  • 迁移学习 入门笔记(1)概念篇
  • 北京南站在哪个区哪个街道建设广告网站需要资质吗
  • 标签与业务系统集成,BarTender助力企业实现全流程自动化生产
  • 单页网站怎么制作建筑工程公司注册要求
  • 山西网站制作公司紧急域名升级更换通知
  • 碰一碰系统源码搭建部署安装步骤详情
  • Ubuntu 22.04.5 安装后无法远程 SSH 连接的排查过程
  • sap和国家网站做接口免费asp网站源码
  • 搜狗网站录入淮安企业网站制作
  • 关于企业网站开发与设计论文网站运营推广该如何做
  • 《云岚到家》第一章个人总结
  • Python 鼠标轨迹算法 - 模拟真人轨迹算法
  • 百度喜欢什么样的网站什么网站能免费做公众号封面