#206 反转链表

题目

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

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

示例 2:
输入:head = [1,2]
输出:[2,1]

示例 3:
输入:head = []
输出:[]

提示:
链表中节点的数目范围是 [0, 5000]
-5000 <= Node.val <= 5000

进阶:链表可以选用迭代或递归方式完成反转。你能否用两种方法解决这道题?

思路

迭代法

  1. 初始化三个指针:
    prev: 指向前一个节点,初始为null(因为第一个节点反转后将指向null)
    curr: 指向当前正在处理的节点,初始为头节点
    next: 用于临时保存下一个节点(在循环中定义)
  2. 使用while循环遍历整个链表:
    循环继续的条件是curr != null,即当前节点不为空
  3. 在每次循环中:
    首先保存curr的下一个节点到next,因为我们即将改变curr.next
    将curr.next指向prev,实现反转
    将prev移动到curr
    将curr移动到next
  4. 循环结束后,prev将指向原链表的最后一个节点,它现在成为反转后链表的头节点
  5. 返回prev作为新的头节点

代码

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */

class Solution {
    public ListNode reverseList(ListNode head) {
        // 初始化三个指针
        ListNode prev = null;  // 前一个节点,初始为null
        ListNode curr = head;  // 当前节点,初始为头节点
        
        // 遍历整个链表
        while (curr != null) {
            // 保存当前节点的下一个节点
            ListNode next = curr.next;
            
            // 反转当前节点的指针,使其指向前一个节点
            curr.next = prev;
            
            // 移动指针
            prev = curr;  // 将前一个节点更新为当前节点
            curr = next;  // 将当前节点更新为下一个节点
        }
        
        // 返回新的头节点,即原链表的最后一个节点
        return prev;
    }
}

复杂复分析

时间复杂度:O(n),其中n是链表的长度,因为我们只遍历了一次链表。
空间复杂度:O(1),因为只使用了固定数量的额外空间(三个指针),不随输入规模变化。

posted @ 2024-08-19 10:52  KenWan  阅读(5)  评论(0编辑  收藏  举报