反转链表

30 阅读1分钟

题目

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

1677204803614.png

1677204836197.png

双指针法

首先可以想到的是重新定义一个数组,实现对链表的反转,但是这样做实际上是对内存空间的浪费。
只需要改变链表的next指针的指向,就可以直接反转链表。

  • 双指针法
    首先定义一个cur指针,指向头节点,再定义一个pre指针,初始化为null; 然后开始反转,如果直接反转,那么cur->next在更新之后会指向pre,之前的cur->next就找不到了,因此应该定义一个节点tmp,保存cur->next。
    之后移动pre和cur指针即可,最后cur指针指向null,循环结束,反转完毕,这是要return pre,因此cur为空,而pre指针指向反转后的链表。
  • 代码
class Solution{
    // 链表节点定义
    public class ListNode {
        int val;
        ListNode next;
        public ListNode() {
        }
        public ListNode(int val) {
            this.val = val;
        }
        public ListNode(int val, ListNode next) {
            this.val = val;
            this.next = next;
        }
    }
    public ListNode reverseList(ListNode head) {
        ListNode pre = null; // 定义一个pre节点,指向null
        ListNode cur = head; // 定义一个cur节点,指向head
        ListNode tmp = new ListNode(); // 定义一个tmp节点,保存cur.next
        while (cur != null){
            tmp = cur.next;
            cur.next = pre;
            pre = cur;
            cur = tmp;
        }
        return pre;
    }
}

递归法

将指针移动的操作使用递归进行。

  • 代码
class Solution {
    public ListNode reverseList(ListNode head) {
        return reverse(null,head);
    }

    public ListNode reverse(ListNode prev,ListNode cur){
        if (cur == null){
            return prev;
        }
        ListNode temp = null;
        temp = cur.next; // 保存下一个节点
        cur.next = prev; // 反转
        return reverse(cur,temp);
    }
}