从尾到头打印链表

从尾到头打印链表

描述

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

示例1

输入:

{67,0,24,58}

返回值:

[58,24,0,67]

这是一道对单链表遍历的入门算法题。但是,我将运用三种方法来解决此题。从而达到学一题等于学三题的目的。
题目难度:一星
考察点:单链表,递归,反转链表


题解


方法一:使用std::reverse()函数

看到题目的第一反应,无非是将单链表遍历一下,(然后思索了几秒,单链表遍历,如何写呢)

while (head) {
    head = head->next;
}

就是这么简单,然后对于此题呢,无非就是遍历的过程中,将结点的值加入到vector中(于是又暗地偷笑,真简单)

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

然后一提交,很不幸,显示wrong,思考了一下,发现忘记反转了,于是又想到了std::reverse()函数

vector<int> printListFromTailToHead(ListNode* head) {
    vector<int> ret;
    while (head) {
        ret.push_back(head->val);
        head = head->next;
    }        
    std::reverse(ret.begin(), ret.end());
    return ret;
}

于是,双手一拍,大公告成,so easy!


方法二:递归版本

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

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;
}

又思考了一下,我记得之前前辈说解题一定要对临界条件进行判断,一般来说就是,题目给的单链表为空,我有没有考虑呢?
表面上,好像没有考虑。实际上,都是有考虑的哦!如果head为空,循环都不会执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

、工藤新一

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值