网站首页 > 精选教程 正文
反转链表这题真的是面试非常喜欢考的了,这题看起来简单,但是能用两种方法一遍 bug free 也是不容易的,面试的时候可以筛下来一大批人,无论是对 junior 还是 senior 面试都很爱考。
今天齐姐就带你梳理清楚思路,思路清楚了才能写码如有神。
题目
这是从力扣中文站上截下来的,但是这个输出不太形象。
对链表的反转,并不是要把它实际翻个个,只是动一动 next 指针就好了。
什么意思呢?
我们先看对数组进行反转。
数组是一个物理上连续存储的数据结构,反转之后原来放 1 的位置就变成了放 5.
但是链表并不是,因为链表在物理上是不连续的,它的每个单元 ListNode
是通过next
指针连接在一起的,而每个 ListNode 之间在内存里并不一定是挨着的。
所以反转链表,就不是非要把 1 的位置放 5,因为它们想在哪在哪。
那么怎么保证这个顺序呢?
就是 next 指针。
沿着 next 指针的方向走下去,就是链表的顺序。这也就保证了,只要我们拿到了头节点,就掌控了整个 LinkedList.
那么题目中的例子,形象点是这个样子滴:
也就是元素自己不用动,只需要动动小指针,就是反转了。
递归解法
递归的三步骤大家还记得吗?
Base case + 拆解 + 组合
不记得的赶紧在公众号内回复「递归」二字,获取递归的入门篇详解。
那么我们来看这个题的:
base case:
当只有一个 node,或者没有 node 了呗,也就是
if(node == || node.next == ) {
return node;
}
其实呢,只剩一个 node 的时候严格来讲并不是 base case,而是 corner case,
因为它本可以再 break down 到 node == 的,但因为后面有对 node.next 的 dereference 操作,所以不能省略。
拆解:
递归的拆解就是把大问题,分解成小一点点的问题,直到 base case 可以返回,进行第三步的组合。
那么这里就是
组合:
组合的意思是,假设我们能够拿到小问题的解,那么用小问题的解去构造大问题的解。
那么这道题如何构造呢?
这里很明显,在 2 后面接上 1 就行了。
但是怎么拿到 2呢?
别忘了,原问题里,此时还有 1 指向 2 呢~
也就是 node1.next = node2
然后把 2 指向 1:node2.next = node1
合起来就是:node1.next.next = node1
思路清楚就不绕,看着觉得绕的就是没想清楚哼~
代码
递归的代码写起来都很简洁:
class Solution {
public ListNode reverseList(ListNode head) {
if(head == || head.next == ) {
return head;
}
ListNode newHead = reverseList(head.next);
head.next.next = head;
head.next = ;
return newHead;
}
}
时间复杂度
我们在「递归」这篇文章里说过,递归的时间复杂度分析方法就是把递归树画出来,每个节点的时间加起来就行了。
这个递归树是一个很简单的单项链表,每个节点上做的就是那三行代码,也就是「组合」做的事,即 O(1) 的时间,总共有 n 个节点,那么总的时间就是 O(n).
空间复杂度
那看递归树也很明显了,每一层也就用了点小变量,是 O(1),所以总的空间共是 O(n).
Iterative 解法
(谁能告诉我这个中文的专业说法。。
Iterative 的思路就是:
过一遍这个 Linked List,边过边把这个 node 的 next 指针指向前面那个 node,直到过完全部。
这样说太抽象,面试时也是,直接过例子。
那也就是把 1 的 next 指针翻过来指向 ;
把 2 的 next 指针翻过来指向 1;
把 3 的 next 指针翻过来指向 2;
...
所以我们还需要一个变量来记录当前 node 的前一个 node,不妨设为 prev.
同时呢,一旦我们把指针翻转过去,后面的那个 node 就丢了有木有!所以还需要有个额外的变量事先记录下后面的 node,设为 nxt,这样才不至于走丢~
Step1.
翻转箭头:把 1 的 next 指针指向 ;
这样子,同时我们也明确了,prev 的初始化应该是 .
然后把这仨变量都移动到下一个位置:
Step2.
翻转箭头:把 2 的 next 指针指向 1,
然后三人行:
Step3.
翻转箭头:把 3 的 next 指针指向 2,
再齐步走:
Step4.
再把 4 的反过来:
再往后走:
Step5.
再把 5 的 next 反过来:
但是因为我们的 while 循环包含了
「翻转箭头」+「三人行」
两个步骤,所以还需要走完最后一个三人行,变成:
很多同学搞不清楚这个 while 循环的结束条件,其实很简单,你就走个例子画画图嘛!
那结束条件就是 curr =
的时候,
最后返回的是 prev
.
好了,看代码吧:
class Solution {
public ListNode reverseList(ListNode head) {
ListNode prev = ;
ListNode curr = head;
while(curr != ) {
ListNode nxt = curr.next;
curr.next = prev; // 翻转箭头
prev = curr; //三人行
curr = nxt; //三人行
}
return prev;
}
}
时间复杂度
这里的时间复杂度很明显了,就是过了一遍这个链表,所以是 O(n).
空间复杂度
空间是 O(1).
-END-
如果看到这里,说明你喜欢这篇文章,请 转发、点赞。同时 标星(置顶)本公众号可以第一时间接受到博文推送。
1. 为什么程序员下班后只关显示器从不关电脑?
最近整理一份面试资料《Java技术栈学习手册》,覆盖了Java技术、面试题精选、Spring全家桶、Nginx、SSM、微服务、数据库、数据结构、架构等等。
猜你喜欢
- 2024-11-02 LeetCode-025-K 个一组翻转链表 每k个一组翻转链表
- 2024-11-02 C++算法(五)反转链表 反转链表c#
- 2024-11-02 61. 旋转链表 反转链表 头插法
- 2024-11-02 字节面试算法集第三题链表反转 #算法
- 2024-11-02 Java数据结构和算法—链表 java中的链表数据结构
- 2024-11-02 面试现场:如何实现链表的逆序? 链表逆置是什么意思
- 2024-11-02 LeetCode-206-反转链表 反转链表 迭代
- 2024-11-02 迭代法 链表翻转 #软件开发 迭代法程序
- 2024-11-02 每日算法---单链表反转和是否有环
- 2024-11-02 C++:挑战鹅厂面试题(一)--反转链表
你 发表评论:
欢迎- 04-11Java面试“字符串三兄弟”String、StringBuilder、StringBuffer
- 04-11Java中你知道几种从字符串中找指定的字符的数量
- 04-11探秘Java面试中问的最多的String、StringBuffer、StringBuilder
- 04-11Python字符串详解与示例(python字符串的常见操作)
- 04-11java正则-取出指定字符串之间的内容
- 04-11String s1 = new String("abc");这句话创建了几个字符串对象?
- 04-11java判断字符串中是否包含某个字符
- 04-11关于java开发中正确的发牌逻辑编写规范
- 最近发表
-
- Java面试“字符串三兄弟”String、StringBuilder、StringBuffer
- Java中你知道几种从字符串中找指定的字符的数量
- 探秘Java面试中问的最多的String、StringBuffer、StringBuilder
- Python字符串详解与示例(python字符串的常见操作)
- java正则-取出指定字符串之间的内容
- String s1 = new String("abc");这句话创建了几个字符串对象?
- java判断字符串中是否包含某个字符
- 关于java开发中正确的发牌逻辑编写规范
- windows、linux如何后台运行jar(并且显示进程名)
- 腾讯大佬私人收藏,GitHub上最受欢迎的100个JAVA库,值得学习
- 标签列表
-
- nginx反向代理 (57)
- nginx日志 (56)
- nginx限制ip访问 (62)
- mac安装nginx (55)
- java和mysql (59)
- java中final (62)
- win10安装java (72)
- java启动参数 (64)
- java链表反转 (64)
- 字符串反转java (72)
- java逻辑运算符 (59)
- java 请求url (65)
- java信号量 (57)
- java定义枚举 (59)
- java字符串压缩 (56)
- java中的反射 (59)
- java 三维数组 (55)
- java插入排序 (68)
- java线程的状态 (62)
- java异步调用 (55)
- java中的异常处理 (62)
- java锁机制 (54)
- java静态内部类 (55)
- java怎么添加图片 (60)
- java 权限框架 (55)
本文暂时没有评论,来添加一个吧(●'◡'●)