剑指Offer24.反转链表 Python3和Java实现
个人认为通过栈实现是比较好理解的一种实现方式,但是时间和空间复杂度都比较高,可以用来学习,如果内容有任何错误,欢迎各位大佬指正!
python代码如下:
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
# 初始化一个列表(当作栈用)
stack = []
# 判断若链表的头结点为空,直接返回该链表
if head == None:
return head
# 遍历链表,将链表中每个节点的值按顺序存入栈stack中(遍历条件为head.next,可以不用从栈中取最后一个元素,hhhh~当然条件为head也是可以的)
while head.next:
stack.append(head.val)
# 不断移动head,使得每次存入栈中的值都是按顺序且向后移动的
head = head.next
# 定义一个新链表的头结点为new_head,并指向原链表的最后一个节点(通过上面的遍历此时的head已经是原链表的尾节点了)
new_head = head
# 定义一个cur,同样指向原链表的最后一个节点
cur = new_head
# 遍历栈,栈不为空就一直弹出最后一个值(注意此时弹出的值,这里栈中如果存的不是值而是节点,会超时,不知道有没有不超时的办法,有的话欢迎留言告诉我!)
while stack:
# 这一步相当于弹出最后一个值,并用这个值新创建一个新节点,并通过cur.next,使得new_head与新节点连接起来(new_head的next为新节点)
cur.next = ListNode(stack.pop())
# 此时cur在本次遍历中功成身退,完成了将new_head和新节点连接起来的工作后,移动到了新节点处
cur = cur.next
# 注意返回的是新链表的头节点,此时的cur已经是新链表的最后一个节点了
return new_head
Java代码如下:
class Solution {
public ListNode reverseList(ListNode head) {
Stack<ListNode> stack = new Stack<ListNode>();
// 必须先判空,否则如果输入空的链表下面的遍历会报空指针异常
if(head == null){
return head;
}
// 和python的区别1是这边可以直接往栈内插入节点,虽然可能效率低一点
while (head.next != null){
stack.push(head);
head = head.next;
}
ListNode new_head = head;
ListNode cur = new_head;
while (!stack.isEmpty()){
cur.next = stack.pop();
cur = cur.next;
}
// 和python的区别2是最后必须让尾节点的next指向null,否则会形成环
cur.next = null;
return new_head;
}
}
补充一个更简洁的方法,该方法适合直接抽取出来作为一个方法使用,适用于一个算法中,需要多次翻转链表的情况
Python3代码:
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
# 方法2
# 首先判空
if head == None:
return head
# 定义一个空的头节点
pre_cur = None
# nex节点可以不提前定义,看个人喜好
nex = None
# 只要节点不为空,就一直循环
while head != None:
# 用nex记录当前节点的下一个节点,否则后面就找不到了
nex = head.next
# 将当前节点的next属性赋值为pre_cur,也就是相当于令当前节点指向了前面一个节点
head.next = pre_cur
# 将pre_cur移动到下一个节点
pre_cur = head
# 将head移动到一开始记录的head节点的下一个节点处
head = nex
# 循环完成后pre_cur已经移动到原链表的最后一个节点处,也就是新链表的头节点,直接返回即可
return pre_cur
Java代码:
class Solution {
public ListNode reverseList(ListNode head) {
if (head == null){
return head;
}
ListNode pre_cur = null;
// 这里next一定要提前定义,其他地方和python基本一致
ListNode next = null;
while (head != null){
next = head.next;
head.next = pre_cur;
pre_cur = head;
head = next;
}
return pre_cur;
}
}