LinkedList专题3

148. Sort List

问题:要求时间度O(NlogN)O(NlogN),空间复杂度是常数,实现数组排序。
思路:之前做过linkedList的插入排序,时间复杂度应该是O(n2)O(n2)。时间复杂度控制在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是比较简单的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/424776.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java面试题1 牛客:A派生出子类B,B派生出子类C,并且在java源代码中有如下声明:

懵逼树上懵逼果&#xff0c;懵逼树下你和我 第一题 [单选题] A派生出子类B&#xff0c;B派生出子类C&#xff0c;并且在java源代码中有如下声明&#xff1a; 1 2 3 A a0new A(); A a1new B(); A a2new C(); 以哪个说法是正确的 A第1行&#xff0c;第2行和第3行的声明都是正…

[Leetcode][第81题][JAVA][N皇后问题][回溯算法]

【问题描述】[困难] 【解答思路】 1. 主副对角线列 标记 复杂度 import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Deque; import java.util.List;public class Solution {private int n;// 记录某一列是否放置了皇后private boolean[] col;// 记…

编码解码错误

python读取文件时提示UnicodeDecodeError错误&#xff1a; "UnicodeDecodeError: gbk codec cant decode byte 0x80 in position 205: illegal multibyte sequence" “UnicodeDecodeError: cp950 codes cant decode byte oxc3 in position 25402: illegal multibyte …

java面试题2 牛客:定义类中成员变量时不可能用到的修饰是

懵逼树上懵逼果&#xff0c;懵逼树下你和我 第二题 定义类中成员变量时不可能用到的修饰是&#xff08;&#xff09; A final B void C protected D static 一看到这道题&#xff0c;有点慌了&#xff0c;直接选c&#xff0c;很显然&#xff0c;我又错了&#xff0c;难题…

[Leetcode][第257题][JAVA][二叉树的所有路径][BFS][DFS]

【问题描述】[简单] 【解答思路】 1. DFS 时间复杂度&#xff1a;O(N^2) 空间复杂度&#xff1a;O(N^2) class Solution {public List<String> binaryTreePaths(TreeNode root) {List<String> paths new ArrayList<String>();constructPaths(root, "…

Depth-first Search深度优先搜索专题1

104. Maximum Depth of Binary Tree 思路&#xff1a;顺着树的一个分支一直数层数直到叶子节点。DFS的思路。这个题目可以练习的是递归转迭代。 代码 695. Max Area of Island 思路&#xff1a;遇到点i,j;如果grid[i][j]没有被访问过&#xff0c;并且等于1&#xff0c;那么…

作用域和数组

作用域 就是一对大括号{} 作用域的的特点在作用域内部声明的变量,只能在这个作用域使用 数组 array 一组类型相同的数(值)1.数组一旦定义好长度就不能改变了2.数组访问摸个数据的方式 数组以下标(index)的方式获取数据 数组的声明 定义10个学员的成绩/两只之间以,隔开…

java面试题3 牛客:下面有关jdbc statement的说法错误的是

下面有关jdbc statement的说法错误的是&#xff1f; A JDBC提供了Statement、PreparedStatement 和 CallableStatement三种方式来执行查询语句&#xff0c; 其中 Statement 用于通用查询&#xff0c; PreparedStatement 用于执行参数化查询&#xff0c;而 CallableStatement则…

Depth-first Search深度优先搜索专题2

199. Binary Tree Right Side View 思路&#xff1a;想要得到树的每一层最右侧元素值&#xff0c;用BFS最方便。先访问左节点再访问右节点&#xff0c;最后访问的一个值就是留下的值。 想要DFS的思路也可以。只是一定要访问所有节点。 代码 491 Increasing Subsequences …

[Leetcode][第60题][JAVA][第k个排列][回溯][DFS][剪枝]

【问题描述】[中等] 【解答思路】 1. 回溯搜索算法 剪枝 &#xff0c;直接来到叶子结点 时间复杂度&#xff1a;O(N^2) 空间复杂度&#xff1a;O(N) import java.util.Arrays;public class Solution {/*** 记录数字是否使用过*/private boolean[] used;/*** 阶乘数组*/priv…

java面试题4 牛客:运行下列代码,运行结果为

第四题&#xff1a;运行下列代码&#xff0c;运行结果为&#xff08;&#xff09; class A {public A() {System.out.println("class A");}{ System.out.println("Im A class"); }static { System.out.println("class A static"); }}public cla…

蓝桥杯-每日刷题-026

奖金提成 一、题目要求 题目描述 企业发放的奖金根据利润提成。 利润I低于100000元的奖金可提10%&#xff1b; 利润高于100000元&#xff0c;低于200000元的&#xff08;100000<I<200000&#xff09;时,低于100000元的部分按10%提成&#xff0c;高于100000元的部分&…

优秀技术人的管理陷阱

写在前面 几乎每一位做软件开发的技术人&#xff0c;都听过类似这样的话&#xff0c;“30 岁以后&#xff0c;身体比不过 20 几岁的年轻人&#xff0c;需要转型做管理了”。这句话理解起来是没有问题的。的确年龄越大身体就越比不过自己 20 多岁的时候&#xff0c;拼体力不够&a…

机器学习中的数学--数学知识复习

机器学习 机器学习三个部分&#xff1a;编程能力数学统计知识业务知识 机器学习分类 1 监督学习&#xff1a;例如分类、房价预测 2 无监督学习&#xff1a;例如聚类 3 强化学习&#xff1a;例如动态系统、机器人控制系统 机器学习算法 是否连续无监督有监督连续聚类 &am…

【数据结构与算法】【算法思想】拓扑排序

一、拓扑排序 拓扑排序是基于依赖关系的节点&#xff0c;根据依赖关系而生成的序列。节点和依赖关系往往要生成有向无环图。类似的问题有&#xff1a;穿衣服裤子的先后关系&#xff0c;生成穿衣序列/专业课程与前置课程形成的课程学习序列/代码编译依赖关系形成的编译顺序序列…

java面试题5 牛客:下列关于JavaBean的说法正确的是:

下列关于JavaBean的说法正确的是&#xff1a; A:Java文件与Bean所定义的类名可以不同&#xff0c;但一定要注意区分字母的大小写 B:在JSP文件中引用Bean&#xff0c;其实就是用语句 C&#xff1a;被引用的Bean文件的文件名后缀为.java D:Bean文件放在任何目录下都可以被引用…

Depth-first Search深度优先搜索专题3

473. Matchsticks to Square 思路&#xff1a;有n根长度不一的火柴&#xff0c;这些火柴可以拼接在一起&#xff0c;但不能被折断。这些火柴能够围城一个正方形吗&#xff1f;每个火柴可以并且必须使用一次。分析得到每个边的长度应该是所有火柴长度和的1/4。接下来就是将火柴…

mysql数据库之事务与存储过程

事务 什么是事务&#xff1f; 事务是指一些SQL语句的集合&#xff0c;这些语句同时执行成功完成某项功能 事务的CAID特性&#xff1a; 原子性&#xff1a;一个事务的执行是整体性的&#xff0c;要么内部所有语句都执行成功&#xff0c;要么一个都别想成功 一致性&#xff1a;事…

java面试题6 牛客:哪个关键字可以对对象加互斥锁?

哪个关键字可以对对象加互斥锁&#xff1f;&#xff08;&#xff09; A synchronized B volatile C serialize D static synchronized的4种用法 1.方法声明时使用,放在范围操作符(public等)之后,返回类型声明(void等)之前.这时,线程获得的是成员锁,即一次只能有一个线程进…

[Leetcode][第347题][JAVA][前K个高频元素][优先队列][堆][遍历set/map]

【问题描述】[中等] 【解答思路】 1. 堆 复杂度 class Solution {public int[] topKFrequent(int[] nums, int k) {Map<Integer, Integer> occurrences new HashMap<Integer, Integer>();for (int num : nums) {occurrences.put(num, occurrences.getOrDefault…