题目:反转链表node
要求:定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。面试
示例:segmentfault
输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL限制:函数
0 <= 节点个数 <= 5000spa
反转链表算是面试中比较常见的一个关于链表的题,总体上难度不大,但若是你能掌握多种的解法,每每能够让面试官眼前一亮指针
注意提醒一点,在面对链表的面试题时,建议多画一下图理解一下code
经过双指针,遍历 head 指针,经过中间变量,逐步指向新的 head 节点,完成链表反转blog
/** * 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 }
结果以下:递归
还有一种简化的写法,在同一步操做中,改变各个变量对应的值,能够省去中间变量,但这样阅读其实并不友好leetcode
/** * 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 }
总体思路是递归到最后一个节点,这个节点就是链表反转后的头节点,这里记做 ret,最终只须要返回这个 ret 指针便可,剩余的都是对中间数据进行指针反转。
具体要怎么分析呢?这样就要画个图了
/** * 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 }
递归去作其实不太容易理解,但也不失为一个巧妙的方法:
这个解法是参考 leetcode 大神的题解的,跟双指针的解法有点像,但更巧妙
/** * 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 }
效果跟简单的双指针没差多少:
欢迎关注公众号:若鱼治水,文章会首发在公众号,也可备注加我备注进群进技术交流群~