反转链表
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
示例一
输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]
示例二
输入:head = [1,2]
输出:[2,1]
示例三
输入:head = []
输出:[]
提示:
- 链表中节点的数目范围是 [0, 5000]
- -5000 <= Node.val <= 5000
进阶: 链表可以选用迭代或递归方式完成反转。你能否用两种方法解决这道题?
解法一
- 得到链表中节点的总数,total,这里使用 while 语句
- 将从头遍历链表,将第n个节点与第total-n个节点的val交换,为了得到total-n个节点需要遍历链表
这种做法并没有反转 Node 实例,只是将它们的值反转了
ts
/**
* Definition for singly-linked list.
* class ListNode {
* val: number
* next: ListNode | null
* constructor(val?: number, next?: ListNode | null) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
* }
*/
function getNode(head: ListNode,NO: number) {
let n = 1
while(head && n < NO) {
head = head.next
n++
}
return head
}
function reverseList(head: ListNode | null): ListNode | null {
let total = 0
let p = head
while(p) {
p = p.next
total ++
}
p = head
let n = 0
let middle = Math.floor(total / 2)
while(p && n < middle) {
const other = getNode(head,total-n)
const temp = p.val
p.val = other.val
other.val = temp
p = p.next
n++
}
return head
};
时间复杂度O(n * n),空间复杂度O(1)
解法二
解法一在查找 total-n 位置上的节点存在重复计算,解法二有一个 Map 保存节点的位置,必须重复计算。
这种做法并没有反转 Node 实例,只是将它们的值反转了
ts
function reverseList(head: ListNode | null): ListNode | null {
let total = 0
let p = head
const nodeMap = new Map<number, ListNode>()
while(p) {
total ++
nodeMap.set(total,p)
p = p.next
}
p = head
let n = 0
let middle = Math.floor(total / 2)
while(p && n < middle) {
const other = nodeMap.get(total-n)
const temp = p.val
p.val = other.val
other.val = temp
p = p.next
n++
}
return head
};
时间复杂度O(n),空间复杂度O(n)
解法三
创建两个指针 result 和 prev,result 是最新的结果链表,prev 是上一次得到的结果链表,它们的初始值都为 null,遍历 head,result 和 prev 的关系是 result.next = prev,
vbscript
/**ts
* Definition for singly-linked list.
* class ListNode {
* val: number
* next: ListNode | null
* constructor(val?: number, next?: ListNode | null) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
* }
*/
function reverseList(head: ListNode | null): ListNode | null {
let result = null
let prev = null
while(head) {
prev = result
result = head
head = head.next
result.next = prev
}
return result
};
时间复杂度O(n),空间复杂度O(1)