剑指offer从尾到头打印链表

今日第二道题,链表、二叉树,虽然有的题目很简单,但是有时就是绕不出来,熟能生巧,见多了练多了就会了,我们一起加油哦~上题:

题目描述
输入一个链表,按链表从尾到头的顺序返回一个ArrayList。


方法一:中间桥梁——空间换时间
分析:需要将链表的值存到列表中,但是链表只能从头遍历,所以必须有个中间值作为桥梁,这里选列表,队列,栈都可以,考虑从尾到头,我就用栈作为中间值;
步骤:
    1、先顺序遍历链表存入到栈中;
    2、然后将栈中数据弹出,存入list中;

代码:
/**
*    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> array = new ArrayList<>();
        Stack<Integer> stack=new Stack<>();
        while(listNode != null){        //存进去
            stack.push(listNode.val);
            listNode=listNode.next;
        }
        while(!stack.isEmpty()){         //拿出来
            array.add(stack.pop());
        }
        return array;
    }
}
牛客运行通过
运行时间:19ms
运行内存:9428Kb

方法二:列表反转
分析:不使用额外的空间,只用列表,最后将列表进行反转;

代码:
/**
*    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> list= new ArrayList<>();
        while(listNode!=null){       //从头到尾存进列表
            list.add(listNode.val);
            listNode=listNode.next;
        }
        int low=0;
        int high=list.size()-1;
        while(low<high){             //将列表反转;
            int temp=list.get(low);
            list.set(low,list.get(high));
            list.set(high,temp);
            low++;
            high--;
        }
        return list;
    }
}
牛客运行通过
运行时间:18ms
运行内存:9304Kb

方法三:利用ArrayList中add(index,element);
代码:
/**
*    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> list= new ArrayList<>();
        while(listNode!=null){
            list.add(0,listNode.val);   //一直将链表中的数插入到第一个
            listNode=listNode.next;
        }
        return list;
    }
}
牛客运行通过
运行时间:18ms
运行内存:9440Kb

方法四:递归
利用系统的“栈”,遍历到尾,在从尾返回存入列表。

代码
import java.util.ArrayList;
public class Solution {
    ArrayList<Integer> list= new ArrayList<>();
    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        if(listNode!=null){
            printListFromTailToHead(listNode.next);//不断递归,到链表尾
            list.add(listNode.val);    //递归结束,从尾开始存入列表。
        }
        return list;
    }
}
牛客运行通过
运行时间:17ms
运行内存:9352Kb

四种方法其实都不需要初始判断,因为如果为空,下面代码不会执行。
方法一利用了额外的空间,利用空间换时间;
方法二只用一个列表存入,再进行反转;
方法三直接利用add(index,element)一步实现,省去了反转,奥利给~
方法四递归的思想,先递归到底,再返回存入。
递归虽然代码简单,但是如果链表很长,则递归太深,反而不好。这时用栈比较合适。

方法实在是太多了~~
只要思想不滑坡,方法总比困难多。
欢迎各位互相监督,互相交流哦~~

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值