翻转链表
最后更新于:2022-04-02 04:22:17
[TOC]
## 翻转链表
### 递归
go 示例:
```
func reverse(head *Node) *Node {
if head.next == nil {
return head
}
last := reverse(head.next)
// 翻转链接
// 如 1->2->3->4->5,把1->2->3->4->5->4
// 既把 4的next的next指向head 4的next为5
// 既把 5的next 指向4
head.next.next = head
// 断掉链表:如把原来的4->5 断掉
head.next = nil
return last
}
```
图示:
![](../images/screenshot_1612189766438.png)
![](../images/screenshot_1612189770835.png)
![](../images/screenshot_1612189775308.png)
![](../images/screenshot_1612189783255.png)
![](../images/screenshot_1612189788681.png)
### 迭代
go 示例
```
func reverse2(head *Node) *Node {
// newHead 为新链表,元素向前追加
var newHead *Node
tmp := head
// head 标识将要被添加的元素
for tmp != nil {
// tmp 指向 head.next
tmp = head.next
// 把最开始的节点指向新节点
// 相当于向前添加一个元素
head.next = newHead
// newHead 更新头,指向新的头
newHead = head
// head 指向下一个节点
head = tmp
}
return newHead
}
```
图示:
![](../images/screenshot_1612190903514.png)
![](../images/screenshot_1612190915665.png)
![](../images/screenshot_1612190920633.png)
![](../images/screenshot_1612190925936.png)
## 反转链表前 N 个节点
```
var succer *Node
func reverseN(head *Node, n int) *Node {
if n == 1 {
//base case 变为 n == 1,反转一个元素,就是它本身,同时要记录后驱节点
succer = head.next
return head
}
n--
last := reverse(head.next, n)
head.next.next = head
head.next = succer
return last
}
```
1. 与全部翻转不同的是,部分翻转,需要将翻转的最后一个值指向未翻转的第一个元素
2. base case 需要记录最后一个翻转的值,返回凭借
![](../images/screenshot_1612363917497.png)
如翻转3个,那么 succer 为3后面的元素 4,然后把head指向4
';