经典算法题-基础-从尾到头打印链表

问题描述

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

要求
时间限制:1秒
空间限制:32768K

方法原型

public ArrayList<Integer> printListFromTailToHead(ListNode listNode)
public class ListNode {
 int val;
 ListNode next = null;
}

解题思路

如果是双向链表,则这种题目就太过于简单了,直接从尾部获取迭代器遍历即可。不过从方法原型所给的ListNode的原型上可以看出,此题是单向链表
单向链表默认只能从头到尾遍历,与题目要求的从尾到头的要求刚好相反。那么此题的关键就变成了如何逆转遍历的路径,自然就会联想到使用先进后出结构的栈。
具体而言,我们可以:

  • 准备一个额外的栈
  • 对于单向链表从头到尾遍历
  • 没遍历到一个链表节点,就将该链表节点入栈
  • 待遍历完链表后,依次取出栈中元素并打印,直到栈为空

以下动图展示了这个过程:

要注意,以上解法中的栈只是逻辑上的概念,实际的编程实现中可以用链表、数组替代它。

相关代码

JAVA版本

因为java的标准包与C++的STL中都有现成的栈数据结构,我们可以直接使用,以下是java代码实现:

package com.shellmad;

import java.util.ArrayList;
import java.util.Stack;

public class Solution {

    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        Stack<Integer> stack = new Stack<>();
        ArrayList<Integer> result = new ArrayList<>();

        // 遍历链表,入栈
        while (listNode != null) {
            stack.push(listNode.val);
            listNode = listNode.next;
        }

        // 出栈
        while (stack.size() != 0) {
            result.add(stack.pop());
        }

        return result;
    }
}

class ListNode {
    public int val;
    public ListNode next = null;
}

C++版本

以下是C++实现:

#include <vector>
using namespace std;

struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
            val(x), next(NULL) {
    }
};

class Solution {
public:
    static vector<int> printListFromTailToHead(ListNode* head)
    {
        vector<int> ArrayList;
        ListNode* pCur = head;
        ListNode* pTail = NULL;
        while (head != pTail)
        {
            pCur = head;
            while (pCur->next != pTail)
            {
                pCur = pCur->next;
            }
            ArrayList.push_back(pCur->val);
            pTail = pCur;
        }
        return ArrayList;
    }
};

猜你喜欢

转载自www.cnblogs.com/shellmad/p/11641009.html