• 剑指Offer编程题(Java实现)——从尾到头打印链表


    题目描述

    输入一个链表,按链表值从尾到头的顺序返回一个ArrayList。

    解题思路

    思路一:使用头插法

    使用头插法可以得到一个逆序的链表。遍历链表,每次将所遍历节点插入到链表的头部。

    头结点和第一个节点的区别:

    • 头结点是在头插法中使用的一个额外节点,这个节点不存储值;
    • 第一个节点就是链表的第一个真正存储值的节点。
    /**
    *    public class ListNode {
    *        int val;
    *        ListNode next = null;
    *
    *        ListNode(int val) {
    *            this.val = val;
    *        }
    *    }
    *
    */
    import java.util.ArrayList;
    public class Solution {
        public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
            ArrayList<Integer> res = new ArrayList<Integer>();
            if(listNode == null) return res;
            ListNode newList = new ListNode(-1);
            while(listNode != null){
                ListNode tmp = listNode.next;
                listNode.next = newList.next;
                newList.next = listNode;
                listNode = tmp;
            }
            while(newList.next != null){
                res.add(newList.next.val);
                newList = newList.next;
            }
            return res;
        }
    }

    运行结果:

    运行时间:17ms

    占用内存:9324k

    类似做法:遍历链表,创建一个新的链表,每次将遍历的节点放在开头

    import java.util.ArrayList;
    public class Solution {
        public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
            ArrayList<Integer> res = new ArrayList<Integer>();
            if(listNode == null) return res;
            ListNode newList = new ListNode(listNode.val);
            ListNode nextNode = listNode.next;
            while(nextNode != null){
                ListNode insert = new ListNode(nextNode.val);
                insert.next = newList;
                newList = insert;
                nextNode = nextNode.next;
            }
            res.add(newList.val);
            nextNode = newList.next;
            while(nextNode != null){
                res.add(nextNode.val);
                nextNode = nextNode.next;
            }
            return res;
        }
    }

    结果:

    运行时间:21ms

    占用内存:9412k

    思路二:递归

    /**
    *    public class ListNode {
    *        int val;
    *        ListNode next = null;
    *
    *        ListNode(int val) {
    *            this.val = val;
    *        }
    *    }
    *
    */
    import java.util.ArrayList;
    public class Solution {
        public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
            // 递归
            ArrayList<Integer> res = new ArrayList<Integer>();
            if(listNode != null){
                res.addAll(printListFromTailToHead(listNode.next));
                res.add(listNode.val);
            }
            return res;
        }
    }

    结果:

    运行时间:19ms

    占用内存:9436k

    思路三:栈

    /**
    *    public class ListNode {
    *        int val;
    *        ListNode next = null;
    *
    *        ListNode(int val) {
    *            this.val = val;
    *        }
    *    }
    *
    */
    import java.util.ArrayList;
    import java.util.Stack;
    public class Solution {
        public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
            //
            Stack<Integer> stk = new Stack<Integer>();
            while(listNode != null){
                stk.add(listNode.val);
                listNode = listNode.next;
            }
            ArrayList<Integer> res = new ArrayList<Integer>();
            while(!stk.isEmpty()){
                res.add(stk.pop());
            }
            return res;
        }
    }

    结果:

    运行时间:22ms

    占用内存:9424k

    思路参考:https://www.nowcoder.com/discuss/198840

  • 相关阅读:
    第十一节 jQuery特殊效果
    第十节 使用index和一个点击事件实现选项卡
    synchronized和lock两种锁的比较
    常见的四种线程池和区别
    mybatis中的#和$的区别
    web 防止SQL注入
    GIT配置免密登录
    热点 Key 问题的发现与解决
    Redis缓存击穿
    面试必问之JVM原理
  • 原文地址:https://www.cnblogs.com/MWCloud/p/11312763.html
Copyright © 2020-2023  润新知