206.反转链表

铭记:

源码下载

206.反转链表

反转一个单链表。
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
进阶:
你可以"迭代"或"递归"地反转链表。你能否用两种方法解决这道题?

一、迭代反转链表

通过迭代可以依次拿到链表节点,然后把节点依次插入到新链表的头部,这样就实现了单链表的反转

1、定义新链表
定义新链表.png

2、迭代链表

  • 迭代第1次
    链表反转-迭代1.png
链表反转-迭代1完成.png
  • 迭代第2次
    链表反转-迭代2.png
    链表反转-迭代2完成.png

代码如下

ListNode

public class ListNode {
    int val;
    ListNode next;

    ListNode(int x) {
        val = x;
    }
}

reverseList方法


    /**
     * 通过迭代来把链表翻转
     * 思路:
     *
     *      1、先定义一个新的链表 new
     *      2、开始迭代链表,先保存当前节点下一个节点 (next)
     *      3、设置当前节点的next指向 新链表 (node.next->new)
     *      4、重新把新链表执行 当前节点:(new = node)
     *      5、这样完成了当前节点插入到新链表
     *
     *      总结:迭代翻转链表的思路就是,通过迭代依次把节点插入到新的链变的0号位置
     */
    public ListNode reverseList(ListNode head) {
        ListNode newHead = null;
        while (null != head) {
            // 1、当前节点next指向的节点
            ListNode nextNode = head.next;
            // 2、当前节点的next指向新链表,到这里已经完成了节点前插
            head.next = newHead;
            // 3、把倒序完成后的链表的第一个节点,重新赋值给新节点
            newHead = head;
            // 4、当前节点的next节点赋值给head节点,用于前插
            head = nextNode;
        }
        return newHead;
    }

二、递归反转链表

思路:使用递归反转链表,首先要明确reverseList方法的作用?reverseList方法的返回值是什么?reverseList方法是用来反转链表的并且返回反转后的新链表。这时只需要处理新链表和head来链接,只需要把head.next.next指向head,而head指向NULL这样就把整个链表反转了

1、当传入head=NULL时,不需要处理直接返回head

2、当传入head.next=NULL时,说明只有一个有效节点,也不需要处理直接返回head

3、当传入head=4时
链表反转-递归传入4.png
链表反转-递归传入4完成.png

4、当传入head=3时
链表反转-递归传入3.png

链表反转-递归传入3完成.png

代码


    /**
     * 通过递归的方式把链表翻转
     * 思路:
     *      首先要明确reverseList方法的作用及返回的节点是什么
     *      reverseList : 把传入的链表翻转
     *      返回ListNode : 翻转后的列表首节点
     *      a、5->NULL : 无需翻转
     *      b、4->5->NULL : 5->4—>NULL
     *          当前 head = 4
     *          那么 head.next = 5
     *          newHead = head.next
     *          head.next.next = head
     *          head.next = NULL
     *          return newHead (5->4->NULL)
     *      c、3->4->5->NULL : 5->4->3->NULL
     *          想想实现翻转,需要先把3之后的链表翻转过来,其实就是b的结果
     *          newHead = 5->4->NULL
     *          head = 3
     *          head.next = 4
     *          head.next.next = 3 (4->3)(5->4->3)
     *          head.next = NULL (5->4->3->NULL)
     *          return newHead
     *
     *      d、2->3->4->5->NULL : 5->4->3->2->NULL
     *          先要翻转head(2)之后的链表,也就是c的结果
     *          newHead = 5->4->3->NULL
     *          此时
     *          head = 2
     *          head.next = 3
     *          只要把2挂到3后,newHead列表就实现了5->4->3->2
     *          head.next.next = 2
     *          head.next = NULL (5->4->3->2->NULL)
     *          return newHead
     *
     */
    public ListNode reverseList(ListNode head) {

        if (head == null || head.next == null) {
            return head;
        }
        ListNode newHead = reverseList(head.next);
        head.next.next = head;
        head.next = null;
        return newHead;
    }

你可能感兴趣的:(206.反转链表)