您的当前位置:首页正文

[链表]从尾到头打印链表

来源:伴沃教育

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

首先是最好写的方法

java的ArrayList可以直接向头部添加新的项
时间复杂度O(n),因为就是遍历一遍,不需要除了输出空间以外额外的空间

import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        //新建一个ArrayList来保存结果
        ArrayList<Integer> res = new ArrayList<Integer>();
        //遍历链表
        while(listNode != null){
            //add(index, E element),向arraylist的第index位插入内容
            res.add(0, listNode.val);
            listNode = listNode.next;
        }
        return res;
    }
}

但是ArrayList向头部存储,会产生重新申请空间,重新分配空间等操作,并不是最优的。
网友说法vector在头部插入,可能需要多次重新分配空间,复制很多次数组

如果程序使用C++编写,还可以使用另一个库:reverse

首先将链表顺序存储进vector,然后使用reverse(vector.begin(), vector.end())来逆序排列
时间复杂度O(n),也是遍历一遍,不需要额外空间

class Solution {
public:
    vector<int> printListFromTailToHead(ListNode* head) {
        vector<int> res;
        //顺序存入
        while(head != NULL){
            res.push_back(head->val);
            head = head->next;
        }
        //颠倒
        reverse(res.begin(), res.end());
        return res;
    }
};

如果不依赖库呢?也是两种实现方式

一:使用栈

先将链表顺序入栈
全部入栈后,再全部弹栈并存储
时间复杂度O(n),入栈+出栈 = n + n,需要额外的O(n)的栈空间

import java.util.ArrayList;
import java.util.Stack;
//引入额外的包Stack
public class Solution {
    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        ArrayList<Integer> res = new ArrayList<Integer>();
        Stack<Integer> stack = new Stack<Integer>();
        
        //入栈
        while(listNode != null){
            stack.push(listNode.val);
            listNode = listNode.next;
        }
        
        //弹栈
        while(!stack.empty()){
            res.add(stack.pop());
        }
        return res;
    }
}

二:使用递归

递归的特点是你可以控制,是顺序加入队列还是逆序(由递归调用的子函数和插入位置决定)

import java.util.ArrayList;
public class Solution {
    private ArrayList<Integer> res = new ArrayList<Integer>();
    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        if(listNode != null){
            //由于是递归调用,因此可能调用到null节点
            printListFromTailToHead(listNode.next);   //1
            res.add(listNode.val);                    //2
            //1和2的顺序,决定了res最终是顺序还是逆序,想想为什么?
        }
        return res;
    }
}
显示全文