剑指Offer面试题:18.反转链表

一、题目
————————————————
题目描述
输入一个链表,反转链表后,输出新链表的表头。
————————————————
二、思路
————————————————
要求很简单,输入一个链表,反转链表后,输出新链表的表头。
  反转链表是有2种方法(递归法,遍历法)实现的,面试官最爱考察的算法无非是斐波那契数列和单链表反转,递归方法实现链表反转比较优雅,但是对于不了解递归的同学来说还是有理解难度的。
方法一:递归法
总体来说,递归法是从最后一个Node开始,在弹栈的过程中将指针顺序置换的。
递归法过程
为了方便理解,我们以 1->2->3->4这个链表来做演示。输出的效果是4->3->2->1
方法二:遍历法
遍历法就是在链表遍历的过程中将指针顺序置换
遍历法
致敬作者:上帝爱吃苹果
致敬链接:https://www.cnblogs.com/keeya/p/9218352.html
致敬博主:决定我们心情的不止是现在这个时候我们所拥有的,更是我们对未来的预期。
————————————————
三、解决问题
————————————————
测试算例 

  1.功能测试(链表有多个或一个结点)

  2.特殊测试(头结点为null)
————————————————

package swordoffer;

/**
 * @author LQ
 * @version 1.0
 * @date 2020-03-23 15:50
 */

import java.util.List;

/**
 * 题目:
 * 输入一个链表,反转链表后,输出新链表的表头。
 * 为了方便理解,我们以 1->2->3->4这个链表来做演示。输出的效果是4->3->2->1
 */
public class Solution18 {
    public static void main(String[] args) {
        Solution18 demo = new Solution18();
        System.out.println("==============================");
        System.out.println("递归test1");
        demo.test1();
        System.out.println("==============================");
        System.out.println("递归test2");
        demo.test2();
        System.out.println("==============================");
        System.out.println("遍历法test1");
        demo.test3();
        System.out.println("==============================");
        System.out.println("遍历法test2");
        demo.test4();
        System.out.println("==============================");
    }
    //1.递归
    //递归实质上就是系统帮你压栈的过程,系统在压栈的时候会保留现场。
    public ListNode ReverseList01(ListNode head) {
        if(null == head || null == head.next){
            return head;
        }
        ListNode temp = head.next;
        //进入递归
        //我们假设此时递归到了3结点,此时head=3结点,temp=3结点.next(实际上是4结点)
        //执行ListNode newHead = ReverseList01(head.next);传入的head.next是4结点,返回的newHead是4结点。
        ListNode newHead = ReverseList01(head.next);
        //接下来就是弹栈过程了
        temp.next = head;//程序继续执行 temp.next = head就相当于4->3
        head.next = null;//head.next = null 即把3结点指向4结点的指针断掉。
        return newHead;//返回新链表的头结点newHead
        //注意:当retuen后,系统会恢复2结点压栈时的现场,此时的head=2结点;temp=2结点.next(3结点),再进行上述的操作。最后完成整个链表的翻转
    }
    //2.遍历法就是在链表遍历的过程中将指针顺序置换
    //依旧是1->2->3->4
    public ListNode ReverseList02(ListNode head) {
        //1、准备两个空结点 pre用来保存先前结点、next用来做临时变量
        ListNode pre = null;
        ListNode cur = null;
        while(head != null){//6、进行下一次循环head=2结点
            cur = head.next;//2、在头结点head遍历的时候此时为1结点 6.1、 cur = 2结点.next(3结点)
            head.next = pre;//3、1结点.next=pre(null)             6.2、2结点.next=pre(1结点)=>即完成2->1
            pre = head;//4、pre = 1结点                           6.3、pre = 2结点
            head = cur;//5、head = 2结点                          6.4、head = 3结点  进行循环...
        }
        return pre;
    }
    //=====================测试代码=======================
    /*
     * 1.功能测试(链表有多个或一个结点)
     */
    void test1() {
        ListNode head1=null;
        ListNode result1=ReverseList01(head1);
        if (null == result1){
            System.out.println("result为null");
        }else{
            while(result1 != null){
                System.out.print(result1.val + " ");
                result1 = result1.next;
            }
        }
    }
    /*
     * 2.特殊测试(头结点为null)
     */
    void test2() {
        ListNode head1=new ListNode(1);
        ListNode node2=new ListNode(2);
        ListNode node3=new ListNode(3);
        ListNode node4=new ListNode(4);
        head1.next=node2;
        node2.next=node3;
        node3.next=node4;
        ListNode result1=ReverseList01(head1);
        if (null == result1){
            System.out.println("");
        }else{
            while(result1 != null){
                System.out.print(result1.val + " ");
                result1 = result1.next;
            }
        }
        System.out.println();
    }

    /*
     * 1.功能测试(链表有多个或一个结点)--方法二:遍历法
     */
    void test3() {
        ListNode head1=null;
        ListNode result1=ReverseList02(head1);
        if (null == result1){
            System.out.println("result为null");
        }else{
            while(result1 != null){
                System.out.print(result1.val + " ");
                result1 = result1.next;
            }
        }
    }
    /*
     * 2.特殊测试(头结点为null)--方法二:遍历法
     */
    void test4() {
        ListNode head1=new ListNode(1);
        ListNode node2=new ListNode(2);
        ListNode node3=new ListNode(3);
        ListNode node4=new ListNode(4);
        head1.next=node2;
        node2.next=node3;
        node3.next=node4;
        ListNode result1=ReverseList02(head1);
        if (null == result1){
            System.out.println("");
        }else{
            while(result1 != null){
                System.out.print(result1.val + " ");
                result1 = result1.next;
            }
        }
        System.out.println();
    }

}

输出
————————————————
努力也是需要学习的,别再让你的努力,只感动了自己!愿你的每一次努力,都能为自己和别人创造价值。

Java基础 文章被收录于专栏

建立本人的Java基础技术栈积累库

全部评论

相关推荐

jack_miller:杜:你不用我那你就用我的美赞臣
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务