剑指Offer (十五):反转链表(Java版)

createh53周前 (04-09)技术教程5

对于一个单向链表来说,上一条数据只能指向下一条数据(如下图),那我们想反转这个链表,变成下图这个样子,怎么实现呢?

1->2->3->4->5      5->4->3->2->1

首先第一种方式,直接反转顺序,将2->1 ,3->2 以此类推,则完成了链表的反转,具体实现为,定义三个指针,pre,cur,next每次遍历链表的时候,cur指向pre,然后再将cur赋值给pre,next赋值给cur,具体代码如下

private static ListNode firstReverse(ListNode listNode){
    if(null == listNode || null == listNode.next){
        return listNode;
    }
    ListNode listNodePre = null;
    ListNode listNodeCur = listNode;
    ListNode listNodeNext = null;
    while (null != listNodeCur){
        listNodeNext = listNodeCur.next;
        listNodeCur.next = listNodePre;
        listNodePre = listNodeCur;
        listNodeCur = listNodeNext;
    }
    return listNodePre;
}

第二种方式,利用栈的特性,先进后出,循环遍历链表进栈,然后依次出栈,组成一个新的链表即可,具体代码如下

private static ListNode secondReverse(ListNode head){
    if(null == head || null == head.next){
        return head;
    }
    ListNode listNodeReverse = null;
    ListNode listNodeFirst = null;
    Stack listNodeStack = new Stack<>();
    while (null != head){
        listNodeStack.push(head);
        head = head.next;
    }
    if(!listNodeStack.isEmpty()){
        listNodeFirst = listNodeStack.pop();
    }
    listNodeReverse = listNodeFirst;
    while (!listNodeStack.isEmpty()){
        listNodeReverse.next = listNodeStack.pop();
        listNodeReverse = listNodeReverse.next;
    }
    listNodeReverse.next = null;
    return listNodeFirst;
}

第三种,则可以采用递归的方式来解决,如果当前节点为空或者当前节点的下一个节点为空,则返回该节点,不然就将该节点的下一个节点指向当前节点,代码如下

private static ListNode thridReverse(ListNode head){
    if(null == head || null == head.next){
        return head;
    }
    ListNode listNodeFirst = head.next;//2
    head.next = null;
    ListNode listNode = thridReverse(listNodeFirst);
    listNodeFirst.next=head;
    return listNode;
}

完整代码如下

public class MainReverseListNode {

    public static void main(String[] args) {

        ListNode listNode0 = new ListNode(1);
        ListNode listNode1 = new ListNode(2);
        ListNode listNode2 = new ListNode(3);
        ListNode listNode3 = new ListNode(4);
        listNode0.next = listNode1;
        listNode1.next = listNode2;
        listNode2.next = listNode3;
        //ListNode reverse = firstReverse(listNode0);
        ListNode secondReverse = thridReverse(listNode0);
        System.out.print(secondReverse.toString());

    }


    private static ListNode firstReverse(ListNode head){
        if(null == head || null == head.next){
            return head;
        }
        ListNode listNodePre = null;
        ListNode listNodeCur = head;
        ListNode listNodeNext = null;
        while (null != listNodeCur){
            listNodeNext = listNodeCur.next;
            listNodeCur.next = listNodePre;
            listNodePre = listNodeCur;
            listNodeCur = listNodeNext;
        }
        return listNodePre;
    }


    private static ListNode secondReverse(ListNode head){
        if(null == head || null == head.next){
            return head;
        }
        ListNode listNodeReverse = null;
        ListNode listNodeFirst = null;
        Stack listNodeStack = new Stack<>();
        while (null != head){
            listNodeStack.push(head);
            head = head.next;
        }
        if(!listNodeStack.isEmpty()){
            listNodeFirst = listNodeStack.pop();
        }
        listNodeReverse = listNodeFirst;
        while (!listNodeStack.isEmpty()){
            listNodeReverse.next = listNodeStack.pop();
            listNodeReverse = listNodeReverse.next;
        }
        listNodeReverse.next = null;
        return listNodeFirst;
    }

    private static ListNode thridReverse(ListNode head){
        if(null == head || null == head.next){
            return head;
        }
        ListNode listNodeFirst = head.next;//2
        head.next = null;
        ListNode listNode = thridReverse(listNodeFirst);
        listNodeFirst.next=head;
        return listNode;
    }

}

相关文章

实现字符串的反转。如:abcd 输出dcba

public class StringReverse { // 方法1: 使用 StringBuilder 的 reverse() 方法 (推荐,高效简洁) public stati...

JAVA 反转链表

输入一个链表,反转链表后,输出新链表的表头。/*public class ListNode { int val; ListNode next = null; ListNode(int val) { t...

几经反转 谷歌胜诉后甲骨文能否接招?丨C位

超过十年的 Java 版权大战在几经反转之后,最终以谷歌的胜利告终。而之后,谷歌的母公司Alphabet还计划在未来几周停用甲骨文的财务软件。面对谷歌的“落井下石”,营收增速放缓的甲骨文能否接招?点击...

Java面试中常见的算法题型

Java面试中常见的算法题型各位小伙伴们,今天咱们来聊聊Java面试中那些让人“脑细胞爆炸”的算法题!这些题目看似简单,但如果你没做好准备,它们可能会像一条条调皮的小泥鳅一样从你的指缝中溜走。不过别担...

深度理解Spring IOC(控制反转)

一、IOC概述Inverse Of Controll即为控制反转,简称IOC 。简单来说,IOC反转了依赖关系的满足方式,由之前的自己创建依赖对象,变为由工厂推送。(变主动为被动,即反转)它解决了具有...