LeetCode反转链表Java实现(含非递归和递归两种解法)

反转链表题目要求

反转一个单链表。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL

非递归方法

思路

    反转链表直白讲就是让每个结点的next引用指向该结点的上一个结点(头结点则是next变为null)。
    第一步,定义引用cur代表当前结点,pre代表上一个结点。cur初始指向头结点,pre初始为null。这里用一个有3个结点的链表来叙述整个过程,如下图1。
在这里插入图片描述

图1

    第二步:循环。
第一次循环
    (1)用临时引用temp指向cur结点的下一个结点,防止cur的next改变指向后访问不到下一个结点。如下图2.1。
在这里插入图片描述

图2.1

    (2)cur的next指向前一结点(这里把null也看做结点),就是将pre值赋给next值。如下图2.2。
在这里插入图片描述

图2.2

    (3)pre和cur都向右移一个结点,具体实现方法即为pre指向cur结点,cur指向temp结点。如下图2.3。
在这里插入图片描述

图2.3

第二次循环
    (1)temp指向cur结点的下一个结点。如下图2.4。
在这里插入图片描述

图2.4

    (2)cur的next指向前一结点。如下图2.5。
在这里插入图片描述

图2.5

    (3)pre和cur都向右移一个结点。如下图2.6。
在这里插入图片描述

图2.6

第三次循环
    (1)temp指向cur结点的下一个结点(这里把null也看做结点)。如下图2.7。
在这里插入图片描述

图2.7

    (2)cur的next指向前一结点。如下图2.8。
在这里插入图片描述

图2.8

    (3)pre和cur都向右移一个结点。如下图2.9。
在这里插入图片描述

图2.9

    到此循环结束,此时cur值为null,可把循环的结束条件定为cur==null。
代码如下,用Java实现。

class ListNode {
    int val;
    ListNode next;
    ListNode(int x) {
        val = x;
    }
}
public class ReverseLinkedList1 {
    public ListNode reverseList(ListNode head) {
        //第一步,定义引用pre指向null,cur指向头结点,cur代表当前结点,pre代表当前结点的上一个结点
        ListNode pre = null;
        ListNode cur = head;
        //第二步,循环。先定义一个临时引用temp指向cur的下一个结点
        ListNode temp = null;
        while (cur != null) {
            //(1)temp指向cur的下一个结点
            temp = cur.next;
            //(2)cur的next指向cur的上一个结点
            cur.next = pre;
            //(3)pre和cur右移,pre指向cur结点,cur指向temp结点
            pre = cur;
            cur = temp;
        }
        //循环结束后,cur和temp都指向null,pre指向原来链表的最后一个结点,此时为已经反转的链表的头结点
        //第三步,head指向最后一个结点
        head = pre;
        return head;
    }

    public static void main(String[] args) {
        ReverseLinkedList1 reverseLinkedList1 = new ReverseLinkedList1();
        //新建链表并依次插入1,2,3,4,5
        ListNode head = new ListNode(1);
        head.next = new ListNode(2);
        head.next.next = new ListNode(3);
        head.next.next.next = new ListNode(4);
        head.next.next.next.next = new ListNode(5);
        ListNode newHead = reverseLinkedList1.reverseList(head);
        ListNode p = newHead;
        while (p != null) {
            System.out.print(p.val + " ");
            p = p.next;
        }
        System.out.println();
    }
}

    运行结果如下:
在这里插入图片描述

递归方法

    递归方法本人并没有想到,这里给出对LeetCode官方给出的递归方法的理解。先上代码。

public class ReverseLinkedList2 {
    public ListNode reverseList(ListNode p) {
        if(p == null || p.next == null) {
            return p;
        }
        ListNode tail = this.reverseList(p.next);
        p.next.next = p;
        p.next = null;
        return tail;
    }

    public static void main(String[] args) {
        //新建链表并依次插入1,2,3,4,5
        ListNode head = new ListNode(1);
        head.next = new ListNode(2);
        head.next.next = new ListNode(3);
        head.next.next.next = new ListNode(4);
        head.next.next.next.next = new ListNode(5);
        ReverseLinkedList2 reverseLinkedList2 = new ReverseLinkedList2();
        //调用头结点的reverseList方法,返回值为原来链表的尾结点,也就是现在新链表的头结点
        ListNode newHead = reverseLinkedList2.reverseList(head);
        //遍历新链表
        ListNode p = newHead;
        while (p != null) {
            System.out.print(p.val + " ");
            p = p.next;
        }
        System.out.println();
    }
}

    main方法中调用头结点的reverseList方法,这个方法内部的执行过程是:
    (1)判断当前结点是否为尾结点,如果是尾结点则返回尾结点;否则继续下一步。
    (2)调用下一结点的reverseList方法。
    (3)反转当前结点。
    除了尾结点,其他结点只有执行过程的后两步。
    所以头结点先调用第2结点的reverseList方法,而第2结点的reverseList方法又会调用第3结点的reverseList方法,这样就递归到尾结点,尾结点只有执行过程的第一步:返回尾结点。
    然后从后往前逐步完成每个结点的reverseList方法:(此时当前结点之后的结点都已完成反转)只有反转自己这一步。最后完成头结点的反转,整个链表就反转完成了。

运行结果如下:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值