「这是我参与11月更文挑战的第22天,活动详情查看:2021最后一次更文挑战」
给你单链表的头节点 head
,请你反转链表,并返回反转后的链表。
示例 1:
输入: head = [1,2,3,4,5]
输出: [5,4,3,2,1]
示例 2:
输入: head = [1,2]
输出: [2,1]
示例 3:
输入: head = []
输出: []
提示:
- 链表中节点的数目范围是
[0, 5000]
-5000 <= Node.val <= 5000
进阶: 链表可以选用迭代或递归方式完成反转。你能否用两种方法解决这道题?
题解1
- 特判如果链表为空或者链表只有一个节点,那么直接返回原链表即可
- 定义一个
pre
指针指向链表头节点 - 定义一个
next
初始化指向头节点,然后让next
指针向后走,在向后走的过程中,将下一个节点的pre
属性指向前一个节点,直到走到链表末尾 - 交换
head
指针和next
指针的值,并让head
指针向后走,next
指针向前走,再次交换两个节点的值,直到两个指针相遇 - 返回头节点即可
整体过程如下:
代码如下:
var reverseList = function(head) {
// 特判
if(head === null || head.next === null) return head;
let pre = head,next = head;
// 让next走到链表末尾并记录节点的pre属性指向前一个节点
while(next.next){
next.next.pre = next;
next = next.next;
}
// 当两个指针不想交的时候,交换两个指针的值,并让两个指针向中间走
while(pre!==next && next.next!==pre){
const nextVal = next.val;
next.val = pre.val;
pre.val = nextVal;
pre = pre.next;
next = next.pre;
}
return head;
};
题解2
- 特判如果链表为空或者链表只有一个节点,那么直接返回原链表即可
- 定义一个
pre
指针指向链表头节点 - 定义一个
next
指针初始化指向head.next
,当next
指针不为空的时候,将next
的pre
属性指向pre
,然后pre
指针、next
指针一起向后走 - 当
next
指针指向null
的时候,pre
指针指向链表最后一个节点,更新next = pre
- 当
next.pre
不为空时,修改next.next
指针指向next.pre
,达到反转链表的目的 - 当
next.pre
为空时,next
指向头节点,将头节点的next
指向null
- 最后
pre
指针指向的之前链表的最后一个节点即为反转后链表的头节点
整体过程如下:
代码如下:
var reverseList =function(head) {
// 特判
if(head === null || head.next === null) return head;
let pre = head,
next = head.next;
// 转为双向链表
while(next){
next.pre = pre;
pre = pre.next;
next = next.next;
}
// 从后向前修改next指针,完成链表反转
next = pre;
while(next.pre){
next.next = next.pre;
next = next.next;
}
// 将头节点的next指向null
next.next = null;
// 之前链表的尾节点即为反转后链表的头节点
return pre;
};
题解3
题解2的解题方法还可以做进一步优化,做到一次遍历即可完成链表反转
解题思路如下:
- 特判如果链表为空或者链表只有一个节点,那么直接返回原链表即可
- 定义
pre
指针指向头节点,next
指针指向head.next
- 将头节点的
next
修改为null
- 将
next
的next
指针指向pre
,然后pre
和next
一起向后走一步,直到next
指向链表最后一个节点,此时,该节点即位反转后链表的头节点,返回该节点即可
整体过程如下:
代码如下:
var reverseList = function(head) {
// 特判
if(head === null || head.next === null) return head;
// 定义两个指针遍历链表
let pre = head,
next = head.next;
// 将头节点的next指向null 因为头节点是反转后链表的尾节点
head.next = null;
// 当next不为空的时候,让下一个节点的next指针指向前一个节点
while(next){
const next_next = next.next;
next.next = pre;
pre = next;
next = next_next;
}
// 返回原始链表的尾节点,即为反转后链表的头节点
return pre;
};
至此我们就完成了 leetcode-206-反转链表
如有任何问题或建议,欢迎留言讨论!