zoukankan      html  css  js  c++  java
  • 从尾到头打印链表

    题目描述

    输入一个链表,从尾到头打印链表每个节点的值。 

    输入描述:

    输入为链表的表头

    输出描述:

    输出为需要打印的“新链表”的表头

    分析:
      链表是一种动态数据结构,是因为在创建链表时,无须知道链表的长度。当插入一个结点时,我们只需为新结点分配内存,然后调整指针的指向,来确保新结点被链接到链表当中。内存分配不是在创建链表时一次性完成的,而是每添加一个结点分配一次内存。由于没有闲置的内存,链表的空间效率比数组高。

      由于链表中的内存不是一次性分配的,因而我们无法保证链表的内存和数组一样是连续的。所以如果想在链表中找到它的第 i 个结点,我们只能从头结点开始,沿着指向下一个结点的指针遍历链表,它的时间效率为o(n)。而数组,我们可以根据下标在o(1)时间内找到第 i 个元素。

    针对本题的思路分析:

        解决这个问题肯定要遍历链表。遍历的顺序是从头到尾的顺序,可输出的顺序是从尾到头。也就是说,第一个遍历到的结点最后一个输出,而最后一个遍历到的结点第一个输出。这就是典型的“后进先出”,我们可以用来实现这种顺序。每经过一个结点时,把该结点放到一个栈中。当遍历完整个链表之后,再从栈顶逐个输出结点的值,此时输出的结点顺序已经反转过来了。

      既然想到了用栈来实现这个函数,而递归在本质上就是一个栈结构,于是很自然的想到了用递归实现。要实现反过来输出链表,我们每访问到一个结点的时候,先递归输出它们后面的结点,再输出该结点的自身,这样链表的输出结果就反过来了。

    /**
    *    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) {
            if(listNode==null){
                ArrayList list=new ArrayList();
                return list;
            }
            Stack<Integer> stack=new Stack<Integer>();
            while(listNode!=null){//将数据压入栈中
                stack.push(listNode.val);
                listNode=listNode.next;
            }
            ArrayList<Integer> arr=new ArrayList<Integer>();
            while(!stack.empty()){
                arr.add(stack.pop());//将栈中的数据弹出再添加到链表中
            }
            return arr;
        }
    }
    

      注意:代码思路借助栈,遍历的时候入栈,由于数据结构中栈的特点是先进后出,所以遍历的过程中压栈,推栈,完了弹栈加到ArrayList中。有两个容易出错的地方:第一,第一次测试用例,{}返回[ ],null是null,而[ ]是new ArrayList()但是没有数据。第二,遍历stack用的方法是!stack.empty()方法,而不是for循环size遍历

     另一种方法:借助递归实现

    /**
    *    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) {
            ArrayList<Integer> list=new ArrayList<Integer>();
            
            ListNode pNode=listNode;//定义一个类似于指针的pNode
            if(pNode!=null){
                if(pNode.next!=null){
                    list=printListFromTailToHead(pNode.next);//递归
                }
                list.add(pNode.val);
            }
            return list;
        }
    }
  • 相关阅读:
    mongodb管理命令
    面试阿里巴巴前端开发工程师电话面试部分
    前端常用性能优化方法
    面试阿里巴巴前端开发工程师笔试部分
    javascript 实现无重复字符的最长子串
    自定义 Flutter 插件(flutter_3des_plugin)步骤,以及上传插件的那些坑。
    Flutter 实现 3des 加密
    flutter 优雅的版本更新处理
    flutter_blue 蓝牙插件实战及那些坑
    Flutter 总结apk打包上架问题(keystore,依赖包下载报错,apk文件项目请求报错等)
  • 原文地址:https://www.cnblogs.com/GumpYan/p/5876036.html
Copyright © 2011-2022 走看看