从尾到头打印链表

链接:https://www.nowcoder.com/questionTerminal/d0267f7f55b3412ba93bd35cfa8e8035?answerType=1&f=discussion
来源:牛客网

改编
方法一
使用栈

class Solution {
public:
    vector<int> printListFromTailToHead(ListNode* head) {
        vector<int> ret;
        stack<int> stas;
        ListNode* p=head;
        while(p!=NULL){
            stas.push(p->val);
            p=p->next;
        }
        while(!stas.empty()){
            int item=stas.top();
            stas.pop();
            ret.push_back(item);
        }
        return ret;
    }
};

 

方法二:递归版本

于是,不甘心只用一种方法写成,于是又在思考着,如果面试官让我写出递归版本,该怎么写呢?
想到之前学习到二叉树的三种递归遍历算法,好像可以拿来用用。

void dfs (TreeNode* root) {
    if (!root) return;
    dfs(root->left);
    dfs(root->right);
    // 处理头结点
}

上面那个就是后续遍历,经研究,可以借鉴,无非二叉树有2个指针,单链表有1个指针,改一下嘛。

vector<int> printListFromTailToHead(ListNode* head) {
    vetor<int> ret;
    if (!head)
        return ret;
    ret = printListFromTailToHead(head->next);
    ret.push_back(head->val);
    return ret;
}

ok! 大功告成!


方法三:反转链表

然后又在想,面试官是不是想考察我反转链表的能力,就算不是,如果我写出了,面试官会不会很惊讶呢?
首先准备一个pre结点初始指向nullptr,表示正在反转结点的前一个结点,再准备一个cur,表示当前正在反转的结点,cur初始化为head。
最后在准备一个temp,表示还未反转的第一个结点。
于是撸起袖子,开工!

vector<int> printListFromTailToHead(ListNode* head) {
    ListNode* pre = nullptr;
    ListNode* cur = head;
    ListNode temp = cur;
    while (cur) {
        temp = cur->next; //需要现保存一下,不然断开了就找不到了
        cur->next = pre;
        pre = cur; // pre 和 cur分别向右边平移
        cur = temp;
    }
    vector<int> ret;
    while (pre) {
        ret.push_back(pre->val);
        pre = pre->next;
    }
    return ret;
}

 

posted on 2021-02-08 16:20  freden  阅读(46)  评论(0编辑  收藏  举报