1. 题目描述
定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
限制:
- 0 <= 节点个数 <= 5000
2. 解题思路
对于链表的操作,实际上就是在操作链表的指针。所以,对于这道题,我们能想到的最直接的方法就是将每个节点的指针指向该节点的前驱节点,这样整个链表就反转过来了,我们需要设置三个指针:分别指向前驱节点,当前节点,后驱节点。
复杂度分析:
- 时间复杂度:O(n),在反转链表时,需要遍历整个链表;
- 空间复杂度:O(1),在遍历链表过程中,不需要额外的空间储存变量。
再尝试着使用递归来实现这个题目:
对于这道题来说,最重要的就是反转的操作:当前节点是head
,那下一个节点就是head.next
,我们只要将head.next
指向head
,就实现了反转。最后只要将head
和head.next
之间的指针断开,就实现了两个节点之间的指针反转。最后在递归执行以上步骤即可。
复杂度分析:
- 时间复杂度:O(n),在反转链表时,递归的深度为n;
- 空间复杂度:O(1),在遍历链表过程中,不需要额外的空间储存变量。
3. 代码实现
第一种方法:
第二种方法:/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @return {ListNode}
*/
var reverseList = function(head) {
let pre = null
let cur = head
while (cur!= null){
let next = cur.next
cur.next = pre
pre = cur
cur = next
}
return pre
};
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @return {ListNode}
*/
var reverseList = function(head) {
if(!head || !head.next){
return head
}
let res = reverseList(head.next)
head.next.next = head
head.next = null
return res
}
4. 提交结果
第一种方法:
第二种方法: