题目描述

反转一个单链表。

示例:

输入: head = [1, 2, 3, 4, 5]
输出: head = [5, 4, 3, 2, 1]

思路分析

这道题我们可以通过画图来梳理具体的步骤:
在这里插入图片描述
图1

如图1所示,我们以head = [1, 4, 3, 2, 5]为例,(a)为原链表,(b)为输出链表。这里我们可以直观地看到改变的只有链表指针的指向,我们进一步细化,以节点1为例:
在这里插入图片描述
图2

如果想改变节点1的前置与后置指针指向,我们需要知道其前置节点与后置节点,之后需要进行如下操作:
在这里插入图片描述
图3

将核心代码单独拿出则有:

newPrev = curr.next; //prepare for new previous-node

// change pointers' direction
newPrev.next = curr;
curr.next = prev;

同样地,我们再来考虑节点4:
在这里插入图片描述
图4

我们对比图3与图4,可以看出核心操作时一样的,但是在代码实现中,需要在操作每个节点后更新newPrevprev.

步骤罗列

  1. 初始化三个指针currnewPrevprev;
  2. curr遍历链表,改变指针方向后更新newPrevprev
  3. 迭代终止条件为curr = null, 返回prev

解题代码

    public static ListNode solution(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }

        //init pointers
        ListNode prev = null;
        ListNode curr = head;
        ListNode nextPrev = null;
        
        
        while(curr != null){
            nextPrev = curr.next;
            curr.next = prev;
            prev = curr;
            curr = nextPrev;
        }
        return prev;    
      
    }

复杂度分析

时间复杂度:我们对数据遍历了一次,时间复杂度为O(N);
空间复杂度:我们没有借助额外的容器,所以空间复杂度为常量级O(1)。

GitHub源码

完整可运行文件请访问GitHub

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐