算法修炼之路——【链表】Leetcode 206 反转链表

文章目录

  • 题目描述
    • 思路分析
    • 步骤罗列
    • 解题代码
    • 复杂度分析
    • GitHub源码

题目描述

反转一个单链表。

示例:

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

思路分析

这道题我们可以通过画图来梳理具体的步骤:
算法修炼之路——【链表】Leetcode 206 反转链表_第1张图片
图1

如图1所示,我们以head = [1, 4, 3, 2, 5]为例,(a)为原链表,(b)为输出链表。这里我们可以直观地看到改变的只有链表指针的指向,我们进一步细化,以节点1为例:
算法修炼之路——【链表】Leetcode 206 反转链表_第2张图片
图2

如果想改变节点1的前置与后置指针指向,我们需要知道其前置节点与后置节点,之后需要进行如下操作:
算法修炼之路——【链表】Leetcode 206 反转链表_第3张图片
图3

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

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

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

同样地,我们再来考虑节点4:
算法修炼之路——【链表】Leetcode 206 反转链表_第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。

你可能感兴趣的:(算法修炼之路,链表,java,算法,leetcode)