《剑指offer》刷题第三篇

从尾到头打印链表
https://www.nowcoder.com/practice/d0267f7f55b3412ba93bd35cfa8e8035?tpId=13&tqId=11156&rp=1&ru=%2Fta%2Fcoding-interviews&qru=%2Fta%2Fcoding-interviews%2Fquestion-ranking

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

解题思路
第一种思路:栈
遍历链表的顺序是从头至尾,输出却要从尾到头,这是典型的“后进先出”,可以用实现这种顺序。每经过一个节点时,把该节点放入栈中,遍历完整个链表时后,再从栈顶输出。

/**
*  struct ListNode {
*        int val;
*        struct ListNode *next;
*        ListNode(int x) :
*              val(x), next(NULL) {
*        }
*  };
*/
class Solution {
public:
 vector<int> printListFromTailToHead(ListNode* head) {
        stack<int> st;
        while (head != nullptr)
            st.push(head->val), head = head->next;
        vector<int> ret;
        while (!st.empty())
            ret.push_back(st.top()), st.pop();
        return ret;
    }
};

第二种思路:递归
每访问到一个节点时,先递归输出它后面的节点,再输出节点自身。递归时有一个问题,当链表非常长的时候,会导致函数调用的层级很深,从而导致函数调用栈溢出。
在Python中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。

class Solution {
public:
    vector<int> printListFromTailToHead(ListNode* head) {
        vector<int> ret;
        dfs(head, ret);
        return ret;
    }

    void dfs(ListNode *head, vector<int> &ret) {
        if (head == nullptr)
            return ;
        dfs(head->next, ret);
        ret.push_back(head->val);
    }
};

补充知识:C++栈的用法

  1. 首先看一下原C++栈的方法的基本用法:
    push(): 向栈内压入一个成员;
    pop(): 从栈顶弹出一个成员;
    empty(): 如果栈为空返回true,否则返回false;
    top(): 返回栈顶,但不删除成员;
    size(): 返回栈内元素的大小。
#include<iostream>
#include<stack>
using namespace std;

int main()
{
    stack <int>stk;
    //入栈
    for(int i=0;i<50;i++){
        stk.push(i);
    }
    cout<<"栈的大小:"<<stk.size()<<endl;
    while(!stk.empty())
    {
        cout<<stk.top()<<endl;
        stk.pop();
    }
    cout<<"栈的大小:"<<stk.size()<<endl;
    return 0;
}

  1. %d 打印十进制整数
    %6d 打印十进制整数,至少6个字符宽
    %f 打印浮点数
    %6f 打印浮点数,至少6个字符宽
    %.2f 打印浮点数,小数点后有两位小数
    %6.2f 打印浮点数,至少6个字符宽,小数点后有两位小数
    %o 八进制
    %x 十六进制
    %c 字符
    %s 字符串
    %% 百分号
    \a 响铃符
    \b 回退符
    \f 换页符
    \n 换行符
    \r 回车符
    \t 横向制表符
    \v 纵向制表符
    \ 反斜杠
    \? 问号
    \’ 单引号
    \” 双引号
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值