网络异常,图片无法展示
|
「这是我参与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-反转链表
如有任何问题或建议,欢迎留言讨论!