网络异常,图片无法展示
|
「这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战」
给定单链表的头节点 head
,请反转链表,并返回反转后的链表的头节点。
示例 1:
网络异常,图片无法展示
|
输入: head = [1,2,3,4,5] 输出: [5,4,3,2,1] 复制代码
示例 2:
网络异常,图片无法展示
|
输入: head = [1,2] 输出: [2,1] 复制代码
示例 3:
输入: head = [] 输出: [] 复制代码
这里我们先说第一种方法:
- 初始化一个变量
vhead = null
; - 循环链表,新建一个链表节点
node
,val
值 = 当前节点的val
,将node
节点的next
指向vhead
,将vhead
=node
,如此循环知道链表的尾结点 - 最后返回
vhead
即可
至此,我们的第一种解题思路就完成了,以下是代码实现
var reverseList = function(head) { let vhead = null, cur = head; while(cur){ const node = new ListNode(cur.val); node .next = vhead; vhead = node; cur = cur.next; } return vhead; } 复制代码
但是上面这种方法,我们创建了对应数量的节点,并开辟了额外的存储空间存储结果链表,那有没有办法可以直接在原链表上操作即可翻转链表呢?
这里我们说一下第二种方法:
- 题目给定的链表为单向链表,我们可以把链表调整为双向链表,即之前每个节点有一个
next
属性指向它的下一个节点,链表遍历只能从头节点到尾节点,双向链表即每个节点除了next
属性还有一个pre
属性(或者其他什么名字),指向它的上一个节点 - 然后我们定义两个指针,
pre
指向头节点,next
指向尾结点,交换两个指针的值,然后pre
向后移动一位,next
向前移动一位,再交换两个指针的值,知道两个指针相遇 - 最后返回
head
节点即可
至此,我们的第二种解题思路就完成了,以下是代码实现
var reverseList = function(head) { if(head === null) return null; let pre = head, next = head.next; while(next){ next.pre = pre; pre = pre.next; next = next.next; } next = pre,pre = head; while(next !== pre && pre.pre !== next){ const nextVal = next.val; next.val = pre.val; pre.val = nextVal; pre = pre.next; next = next.pre; } return head; } 复制代码
至此,我们就完成了leetcode-剑指offer24-翻转链表
如有任何问题或建议,欢迎留言讨论!