法一 新建数组,倒序存储

一遍历得长度,据此新建等长数组,二遍历倒序存储

时间复杂度:O(N),但是是两次 空间复杂度:O(N)

    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        //创建一等长数组,逆序存储
        ListNode p = listNode;
        int n = 0;
        while(p != null){
            n++;
            p = p.next;
        }
        
        int[] res = new int[n];
        int i = n-1;
        p = listNode;
        while(p != null && i >=0){
            res[i] = p.val;
            p = p.next;
            i--;
        }
      	//注意这种写法
        return new ArrayList<Integer>(){
            {
                for(int t: res){
                    add(t);
                }
            }
        };

alt

可见,这种很差劲

法二 使用辅助栈

一次遍历,元素入栈;再次遍历,出栈到结果ArrayList中

时间复杂度:O(N),两次

空间复杂度:O(N)

    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        //使用辅助栈
        Deque<Integer> stack = new LinkedList<Integer>();
        ListNode p = listNode;
        
        while(p != null){
            stack.push(p.val);
            p = p.next;
        }
        ArrayList<Integer> res = new ArrayList<Integer>();
        while(!stack.isEmpty()){
            res.add(stack.pop());
        }       
        return res;
    }

alt

可见,效率依然很差

法三 直接遍历,后反转ArrayList

    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        ListNode p = listNode;
        ArrayList<Integer> res = new ArrayList<Integer>();
        
        while(p != null){
            res.add(p.val);
            p = p.next;
        }
        Collections.reverse(res);
        return res;
    }

alt

依然很差

法四 反转链表,然后遍历添加

    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        ListNode p = listNode;
        ArrayList<Integer> res = new ArrayList<Integer>();
        p = reverse(p);
        while(p != null){
            res.add(p.val);
            p = p.next;
        }       
        return res;
    }
    
    private ListNode reverse(ListNode head){
        ListNode pre = null,
            cur = head,
            temp = cur;
        while(cur != null){
            temp = cur.next;
            cur.next = pre;
            pre = cur;
            cur = temp;
        }
        return pre;
    }

为什么还是这么差

alt