go程序员面试算法宝典 pdf_Go算法面试题:反转链表

本文介绍了在面试中常见的链表问题——反转链表,详细讲解了使用简单双指针、递归和双头指针三种方法来解决,并提供了每种方法的实现思路和效果。通过实例解析,帮助面试者理解和掌握链表反转技巧。
摘要由CSDN通过智能技术生成

题目:反转链表

要求:定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。

示例:

输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL

限制:

0 <= 节点个数 <= 5000

反转链表算是面试中比较常见的一个关于链表的题,整体上难度不大,但如果你能掌握多种的解法,往往可以让面试官眼前一亮

注意提醒一点,在面对链表的面试题时,建议多画一下图理解一下

解法1:简单双指针

fe67e65d064206ba238e904d3ff99c73.gif

通过双指针,遍历 head 指针,通过中间变量,逐步指向新的 head 节点,完成链表反转

/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func reverseList(head *ListNode) *ListNode {
if head == nil {
return nil
}

var newHead *ListNode
for head != nil {
node := head.Next
head.Next = newHead
newHead = head
head = node
}

return newHead
}

结果如下:

8dd6bef99a73ca4bece46bfebec87067.png

还有一种简化的写法,在同一步操作中,改变各个变量对应的值,可以省去中间变量,但这样阅读其实并不友好

/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func reverseList(head *ListNode) *ListNode {
if head == nil {
return nil
}

var newHead *ListNode
for head != nil {
head, head.Next,newHead = head.Next, newHead, head
}

return newHead
}

跑出来的结果差不多:

2bf4d4787bf1439a50d1b4c0ccae6d0a.png

解法2:递归

整体思路是递归到最后一个节点,这个节点就是链表反转后的头节点,这里记作 ret,最终只需要返回这个 ret 指针即可,剩余的都是对中间数据进行指针反转。

具体要怎么分析呢?这样就要画个图了

e7656ccb5b50c2d13a31ba6f8672ab73.png

05695e8b93c46121d97238a1c8d1c288.gif

/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func reverseList(head *ListNode) *ListNode {
if head == nil || head.Next == nil {
return head
}

ret := reverseList(head.Next)
head.Next.Next = head
head.Next = nil
return ret
}

递归去做其实不太容易理解,但也不失为一个巧妙的方法:

e855222a33feceaef924476642bc6184.png

解法3:双头指针

这个解法是参考 leetcode 大神的题解的,跟双指针的解法有点像,但更巧妙

b07f968d1961045d1075ffd3f5972f04.gif

/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func reverseList(head *ListNode) *ListNode {
if head == nil {
return nil
}

cur := head
for head.Next != nil {
t := head.Next.Next
head.Next.Next = cur // 反转原指针方向
cur = head.Next // 将新头节点移到下一位
head.Next = t // 连接回断开的地方,继续重复上面操作
}

return cur
}

效果跟简单的双指针没差多少:

5a9269037814e19df654fb1c9f5931ed.png

ps:文中动图都来自 leetcode 某大神 ppt 制作的

推荐阅读

  • Go算法面试题:从尾到头打印链表


喜欢本文的朋友,欢迎关注“Go语言中文网”:

2b053189eafb5361b89afea460dbb147.png

Go语言中文网启用微信学习交流群,欢迎加微信:274768166,投稿亦欢迎

你“在看”我吗?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值