剑指Offer-题6(Java版):从尾到头打印链表

参考自:《剑指Offer——名企面试官精讲典型编程题》

题目:从尾到头打印链表
输入一个链表的头结点,从尾到头反过来打印出每个结点的值。

主要思路:借助栈的后进先出特点,从头到尾添加数值到栈中,然后从栈中取出元素。另外也可以借助递归,递归实质上用到方法栈,但递归可能会导致方法栈溢出。

关键点:后进先出,递归

时间复杂度:O(链表长度)

public class ListFromTailToHead {

    public static void main(String[] args) {
        int[] data = {3, 4, 5, 7};
        ListNode pHead = LinkedListData.generateDataByArray(data);
        List<Integer> numbers = printListFromTailToHeadByStack(pHead);
        System.out.println(numbers.toString());
    }

    /**
     * 使用递归。链表太长的时候,容易导致方法栈溢出
     *
     * @param listNode the list node
     * @return array list
     */
    private static List<Integer> printListFromTailToHeadByRecursion(ListNode listNode, List<Integer> result) {
        if (listNode != null) {
            while (listNode.next != null) {
                result = printListFromTailToHeadByRecursion(listNode.next, result);
            }
            //遍历到链表尾部时,再开始添加节点值
            result.add(listNode.val);
        }
        return result;
    }

    /**
     * 借助栈的特性,鲁棒性更好
     *
     * @param listNode the list node
     * @return list
     */
    private static List<Integer> printListFromTailToHeadByStack(ListNode listNode) {

        Stack<Integer> stackRecords = new Stack<>();
        while (listNode != null) {
            stackRecords.push(listNode.val);
            listNode = listNode.next;
        }
        List<Integer> result = new ArrayList<>();
        while (!stackRecords.isEmpty()) {
            result.add(stackRecords.pop());
        }
        return result;
    }
}

class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}

class LinkedListData
{
    /**
     * 根据数组生成链表
     *
     * @param data the data
     * @return list node
     */
    public static ListNode generateDataByArray(int[] data) {
        ListNode head = new ListNode(data[0]);
        ListNode currentNode = head;
        for (int i = 1; i < data.length; i++) {
            ListNode next = new ListNode(data[i]);
            currentNode.next = next;
            currentNode = next;
        }
        return head;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值