剑指Offer-06:从尾到头打印链表

输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。

示例 1:

输入:head = [1,3,2]
输出:[2,3,1]

限制:

0 <= 链表长度 <= 10000

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/cong-wei-dao-tou-da-yin-lian-biao-lcof

思路1:解决这个问题肯定要遍历链表。遍历的顺序是从头到尾的顺序,可输出的顺序却是从尾到头。也就是说第一个遍历到的结点最后一个输出,而最后一个遍历到的结点第一个输出。这就是典型的“后进先出”,我们可以用栈实现这种顺序。
解法1:

public int[] reversePrint(ListNode head) {
       Stack<ListNode> stack=new Stack<>();

       ListNode temp=head;

       while (temp!=null){
           stack.push(temp);
           temp=temp.next;//如果往下走 就要用temp来判断是否为null
       }

        int size=stack.size();
       int[] res=new int[size];
       //size 一定要提前算出来 不要用stack.size()
        for (int i = 0; i < size; i++) {
            res[i]=stack.pop().val;
        }
        return res;
   }

思路2:都可以用栈实现了 那么递归也一定是可以的。但是如果链表过长的话。可能会导致函数调用的层级很深,导致函数调用栈溢出,所以用栈的鲁棒性要更好一点。
解法2

List<Integer> list=new ArrayList<>();
    public int[] reversePrint(ListNode head) {

        dfs(head);
        
        int len=list.size();
        int[] res=new int[len];
        for (int i = 0; i <len ; i++) {
            res[i]=list.get(i);
        }

        return res;


}
		//递归三要素
		void dfs(ListNode node){
		        //1:终止条件
		      if (node==null)
		          return;
		      //返回值为null 不需要管
		      dfs(node.next);
		      //3:本层递归要干什么
		      list.add(node.val);
		
		}

思路3:有没有更优的呢?发现上两个的空间复杂度都是O(n),假如先遍历这个链表,提前算出这个链表的长度,然后在重新遍历下链表进行赋值是不是可以!看代码!
解法3

public int[] reversePrint(ListNode head) {
		
        if (head == null)
            return new int[0];
        ListNode temp = head;
		int len=0;
        //计算出链表的长度
        while (temp != null) {
            len++;
            temp=temp.next;
        }

        int[] res=new int[len];
        int i=1;
        while (head!=null){
            res[len-i]=head.val;
            head=head.next;
            i++;
        }

        return res;
}

这个应该是最优算法了,空间复杂度O(1) 时间复杂度O(n)!

记录一下,2021.4.5 11:04!天气晴朗,阳光明媚!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值