动画:面试如何轻松反转链表?

Posted 小鹿动画学编程

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动画:面试如何轻松反转链表?相关的知识,希望对你有一定的参考价值。

通常我们在面试中面试官给我们出以下题目:

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

例如:

为了能够更加清晰的写明解题思路,所以像往常一样,还是用动画去分步解析。


一、问题分析

反转链表,首先想到的是让最后一个结点作为头结点,第一个结点作为尾结点指向 null。

如果我们把指针反方向改变,就可以轻松完成整个链表的反转。

说到改变指针,我们有两个方式,第一种是从前到后改变指针,第二种是从后往前改变指针。从前往后代表迭代方式,从后往前是递归的方式,这个不难理解,直接上动画。

二、动画实现

递归法:

迭代法:



三、解题思路

迭代法

从前到后开始反转,我们需要三个指针,第一个指针指向当前头结点 head,第二个指针指向第二个节点 curP(当前结点),第三个指针为保存下一个节点的临时节点 temp。

1、反转顺序为,先保存下一节点。

2、然后让当前结点的指向前一节点。

3、最后移动当前结点到下一结点。(head 头节点一开始初始化指向 null)。

4、重复该循环。

递归法

递归法只不过换了一个顺序,先递进去,然后在执行以上反转操作。

1、让当前结点的下一节点的下一节点指向当前结点。

2、当前节点的下一结点指向 null,直到递归完毕,完成反转。


四、代码实现

//& 反转链表 - 递归实现
var reverseList = function(curP) 
  if(curP == null || curP.next == null) return curP;
  var tail = reverseList(curP.next)
  curP.next.next = curP
  curP.next = null
  return tail;
;

//& 反转链表 — 迭代实现
var reverseList = function(head) 
  if(head == null || head.next == null) return head;
  var curP = head.next
  head.next = null
  var temp = null
  while(curP !== null)
    temp = curP.next
    curP.next = head
    head = curP
    curP = temp
  
  return head;
 

java

//& 反转链表 - 迭代实现
class Solution 
    public ListNode reverseList(ListNode head) 
        if(head == null) return null;
        ListNode pre = null;
        ListNode curP= head;
        while(curP != null)
            ListNode temp = curP.next;
            curP.next = pre;
            pre = curP;
            curP = temp;
        
        return  pre;
    


//& 反转链表 — 递归实现
class Solution 
    public ListNode reverseList(ListNode head) 
        if(head == null || head.next == null) return head;
        ListNode tail = reverseList(head.next);
        head.next.next = head;
        head.next = null;
        return tail;
    

python

//& 反转链表 - 迭代实现
class Solution:
    def ReverseList(self, pHead):
        if not pHead or not pHead.next:
            return pHead
        last = None 
        while pHead:
            tmp = pHead.next   
            pHead.next = last
            last = pHead
            pHead = tmp
        return last

//& 反转链表 — 递归实现
class Solution:
    def reverseList(self, head: ListNode) -> ListNode:
        if not head:
            return None
        if not head.next:
            return head
        headNode = self.reverseList(head.next)
        head.next.next = head
        head.next = None
        return headNode

五、性能分析

1、迭代法:

时间复杂度:需要遍历链表的整个长度,由链表长度决定,复杂度为 O(n)。
空间复杂度:需要临时的变量空间,为 O(1)

2、递归法:

时间复杂度:需要遍历链表的整个长度,由链表长度决定,复杂度为 O(n)。
空间复杂度:使用的额外栈空间内存,空间复杂度为 O(n)。


六、测试用例

  • 输入空的头结点(null)

  • 输入一个节点的链表

  • 输入多个节点的链表


作者Info:

【作者】:小鹿

【原创公众号】:小鹿动画学编程。

【简介】:一个喜欢用动画讲解技术的程序员
【转载说明】:转载请说明出处,谢谢合作!~

以上是关于动画:面试如何轻松反转链表?的主要内容,如果未能解决你的问题,请参考以下文章

动画:面试官问我插入排序和冒泡排序哪个更牛逼?

动画:面试算法之求二叉树的下一节点

如何链表反转

动画:看动画轻松理解「递归」与「动态规划」

面试必备的「反转链表」

最强解析面试题:链表反转[go版]