148. Sort List

问题:要求时间度O(NlogN)O(NlogN)O(NlogN),空间复杂度是常数,实现数组排序。
思路:之前做过linkedList的插入排序,时间复杂度应该是O(n2)O(n2)O(n^2)。时间复杂度控制在nlogn 一定有二分。二分我只在数组版的list中用过。从头和尾开始查找,如此之类。这里好像有点难。
学习:把列表分成两部分;分别排序;再合并。这个又被称为分治法。确实是这样。找到一个列表的中间位置,前面的习题练习过了,合并两个数组也练习过。写出递归版的代码还是没有难度的。代码。因为有栈空间的消耗,所以空间复杂度不是常数,而是logn。
学习2:使用自底向上的策略消除递归。这种思路在23 Merge k Sorted Lists 中遇到过。不过我的问题是怎么处理合并后的各个节点。学习别人的代码吧。
解决方法1:例如链表 -1->5->8->4->6。第一步要合并排序 -1,5;8,4;6,null,调用merge函数3次,第一步合并结束后得到的链表应该是-1->5->4->8->6。第二步需要合并-1->5,4->8;6,null;调用merge函数2次,第二步合并之后得到链表-1->4->5->8。第三步需要合并-1->4->5->8,6;调用merge函数一次,得到-1->4->5->6->8。
这里考虑的代码细节是:每一步中一个小的合并例如-1,5形成-1->5这样的列表;5就是下一个合并后列表(4->8)的表头。

    public ListNode sortList(ListNode head) {if (head == null || head.next == null) return head;int length = 0;ListNode node = head;while(node!=null){length++;node = node.next;}ListNode dummy = new ListNode(-1);for(int step = 1;step<length; step<<=1){ListNode tail = dummy;//每一次处理的队列的队尾ListNode curr = head;while(curr!=null){ListNode left = curr;ListNode right = null;right = split(left,step);//从left开始,数step个节点作为第二个列表的头节点curr = split(right,step);//从right开始,数step个节点,返回的节点用于下次合并tail = merge(left,right,tail);}head = dummy.next;}return dummy.next;}private ListNode split(ListNode head, int step) {for (int i = 1; head != null && i < step; i++) {// 少走一步head = head.next;}if (head == null)return null;ListNode tmp = head.next;head.next = null;return tmp;}private ListNode merge(ListNode l1, ListNode l2, ListNode head) {ListNode cur = head;while (l1 != null && l2 != null) {if (l1.val < l2.val) {cur.next = l1;l1 = l1.next;} else {cur.next = l2;l2 = l2.next;}cur = cur.next;}if (l1 != null) cur.next = l1;if (l2 != null) cur.next = l2;while (cur.next != null) {cur = cur.next;}return cur;}

时间复杂度分析:for循环里面split会遍历n个节点,merge会遍历n个节点,是O(2n)。for循环会执行logn次。所以时间复杂度O(nlogn)。

解决方法2:当需要合并步长为1的两个子链表的时候,合并后的结果放入队列中,下次直接从队列中取子链表合并也是可以的。空间复杂度是O(n)了。

    public ListNode sortList(ListNode head) {if (head == null || head.next == null)return head;Queue<ListNode> queue = new LinkedList<ListNode>();ListNode node = head;while (node != null) {ListNode tmp = node.next;node.next = null;queue.add(node);node = tmp;}while(queue.size()>1){queue.add(merge(queue.poll(), queue.poll()));}return queue.poll();}public ListNode merge(ListNode l1, ListNode l2) {if (l1 == null || l2 == null) {return l1 == null ? l2 : l1;}ListNode result = new ListNode(0);ListNode preNode = result;while (l1 != null && l2 != null) {if (l1.val <= l2.val) {preNode.next = l1;l1 = l1.next;} else {preNode.next = l2;l2 = l2.next;}preNode = preNode.next;}if (l1 != null) {preNode.next = l1;}if (l2 != null) {preNode.next = l2;}return result.next;}

代码V1
代码V2
代码V3

328 Odd Even Linked List

思路:按照tag刷题,尤其是从easy到hard,你会发现有些难的题目是多个简单题目的组合。一个一个小问题击破了,难题就解决了。
代码

109 Convert Sorted List to Binary Search Tree

思路: 初看题目是没有思路的。从左到右开始构建树,想什么情况下该把根节点变为左子树;左子树为空的时候不能加右子树,之类的….脑子里一直在想着数据结构书中讲的从非平衡树到平衡树的转换。
学习:整体观察后发现链表的中间节点middle是根;middle的左侧是根的左子树;middle的右侧是根的右子树。
代码

138. Copy List with Random Pointer

思路:深度科隆要求每个对象都要new,包括每个对象的Object类型的属性。这里要处理的问题就是死循环。我的思路是迭代。
学习:可以先用一层循环把所有的node new出新的对应节点;再用第二层循环为每个节点赋值next和random属性。
代码

817 Linked List Components

思路:遍历输入的LinkedList head,如果发现当前节点node.val在G中,而node.next.val不在G中,那结果加1.
代码

725 Split Linked List in Parts

思路:把一个linkedlist分成k份,每份长度差不超过1。那就是把linkedList均分为k份。对于余数的部分分在前面的子链表中。
代码

2 Add Two Numbers

思路:用两个列表表示两个整数,并且是从低位到高位的顺序。例如数字是345,链表是5->4->3。直接计算两个列表对应位置的和。如果满10,就用carry变量保存。再加下一位的时候加上carry。网页
代码

445 Add Two Numbers II

思路:把两个linkedList反转,用上题的思路做。最后再将结果反转。
代码
LinkedList结束。相对来讲,LinkedList是比较简单的。

LinkedList专题3相关推荐

  1. LinkedList专题2

    203 Remove Linked List Elements 思路:考虑1 : 可能有多个节点符合:考虑2:命中节点是head:考虑3:命中节点是尾节点:考虑4:命中节点是中间的普通节点. 学习1: ...

  2. LinkedList专题1

    237 Delete Node in a Linked List 思路:单向链表,只给定要删除的节点.怎么删除这个节点.参考.例如要删除节点node.一般来说我们需要将node.preNode.nex ...

  3. python扫雷 广度优先_Leetcode之广度优先搜索(BFS)专题-529. 扫雷游戏(Minesweeper)...

    Leetcode之广度优先搜索(BFS)专题-529. 扫雷游戏(Minesweeper) BFS入门详解:Leetcode之广度优先搜索(BFS)专题-429. N叉树的层序遍历(N-ary Tre ...

  4. hashmap中用红黑树不用其他树_HashMap面试专题:常问六题深入解析

    引言 其实我很早以前就想写一篇关于HashMap的面试专题.对于JAVA求职者来说,HashMap可谓是集合类的重中之重,甚至你在复习的时候,其他集合类都不用看,专攻HashMap即可. 然而,鉴于网 ...

  5. Redis专题-底层数据结构与使用场景

    Redis介绍 Redis是一种基于键值对的NoSQL数据库,是一个基于内存中的数据结构存储系统,可以用作数据库.缓存和消息中间件.它支持以string(字符串),hash(哈希),list(列表), ...

  6. 回溯专题leetcode

    这期刷leetcode上所有的回溯专题 93. 复原IP地址 这题先不考虑一些剪枝类问题,只是单纯考虑AC,我们设置的两个参数,一个index表示索引到哪个字符串下标了,另一个strs双端队列放入表示 ...

  7. LeetCode算法题-Design LinkedList(Java实现)

    这是悦乐书的第300次更新,第319篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第168题(顺位题号是707).设计链表的实现.您可以选择使用单链表或双链表.单链表中的 ...

  8. 20210501:字符串与哈希表力扣专题学习记录

    字符串与哈希表力扣专题学习记录 题目 思路与算法 代码实现 写在最后 题目 字母异位词分组 无重复字符的最长子串 重复的DNA序列 最小覆盖子串 思路与算法 字母异位词分组 : 按照字母序排序后再映射 ...

  9. JAVA集合专题+源码分析

    文章目录 Java集合专题 集合和数组的区别 数组 集合 区别 集合体系结构介绍 单列集合 [Collection ] Collection接口 迭代器 迭代器原理 增强for循环 List接口 对集 ...

最新文章

  1. 【廖雪峰python入门笔记】set
  2. 华为系列交换机日志服务器的搭建
  3. 基于增强现实和脑机接口的机械臂控制系统
  4. 有赞11·11:全链路压测方案设计与实施详解
  5. 因为应用程序的并行配置不正确 sxstrace
  6. Java数据结构和算法:HashMap,哈希表,哈希函数
  7. OCP12C题库,62数据库备份与恢复(admin,install and upgrade accelerated, backup and recovery workshop -62)(新增)
  8. android原生调用nextjs方法,详解使用Next.js构建服务端渲染应用
  9. mysql 数据透视_sql怎么做数据透视表
  10. linux手动注入网络数据_Linux网络 - 数据包的接收过程【转】
  11. mysql高性能学习笔记03_《高性能MySQL》学习笔记——第三章 服务器性能剖析
  12. Excel数据分析实例
  13. jq UI-引入、拖动效果、api文档位置
  14. JavaScript统计图表插件 Echarts
  15. 线性规划(一):基本概念
  16. 解决Mscomctl.ocx丢失的问题
  17. 两分钟带你彻底明白机器学习中的过采样和欠采样是什么意思?
  18. 七牛云 阿里云图片存储 新增套餐 分页 定时任务Quartz(作业:编辑和删除功能)
  19. 程序员抛弃大厂涌进工厂!南洋理工海归:这里上班比整天盯着电脑有意思的多!...
  20. 教你怎么合理选购LED透明屏_LED透明屏价格影响因素

热门文章

  1. iframe在ipad safari的显示
  2. jQuery css详解
  3. iOS手势UIGustureRecognizer
  4. Qt+ArcGIS Engine 10.1 开发(一)
  5. android dialog 点击确定不消失,AlertDialog点击按钮不消失的实现方法
  6. 安卓真机如何连接本地服务器_一分钟搭建可供手机访问的本地服务器 (安卓,ios手机通用)...
  7. Android textview 获取url,获取电话号码
  8. docker删除所有镜像和容器
  9. interface接口_接口 interface
  10. 1040. 有几个PAT(25