剑指Offer--005-从尾到头打印链表
来源:互联网 发布:淘宝点收藏没反应 编辑:程序博客网 时间:2024/06/06 02:27
链接
牛客OJ:从尾到头打印链表
九度OJ:http://ac.jobdu.com/problem.php?pid=1511
GitHub代码: 005-从尾到头打印链表
CSDN题解:剑指Offer–005-从尾到头打印链表
你也可以选择回到目录–剑指Offer–题集目录索引
题意
题目描述
输入一个链表,从尾到头打印链表每个节点的值。
输入描述:
输入为链表的表头
输出描述:
输出为需要打印的“新链表”的表头
反转链表
首先我们想到的就是反转链表了,如果把链表反转了,然后再返回头,这样再次遍历的时候就相当于从尾到头打印了。
但是修改输入数据真的可行么?
剑指Offer中为我们在面试中提出了如下小提示
在面试时候,如果我们打算修改输入的数据,最好先问问面试官是不是允许修改
通常打印只是一个只读操作,我们肯定不希望输入时候修改链表的内容
利用栈的后进先出特性
单链表的遍历只能从前往后,但是需要从尾往头输出,这不是典型的”先进后出”么,那么我们可以用栈模拟输出
每经过一个结点的时候,把该结点放到一个栈中。当遍历完整个链表后,再从栈顶开始逐个输出结点的值,此时输出的结点的顺序已经反转过来了。
代码如下
#include <iostream>#include <stack>#include <vector>using namespace std;// 调试开关#define __tmain main#ifdef __tmain#define dout cout#else#define dout 0 && cout#endif // __tmain#ifdef __tmainstruct ListNode{public : int val; struct ListNode *next; /*ListNode(int x) : val(x), next(NULL) { }*/};#endif // __tmain/*** struct ListNode {* int val;* struct ListNode *next;* ListNode(int x) :* val(x), next(NULL) {* }* };*/class Solution{public: vector<int> printListFromTailToHead(struct ListNode* head) { ListNode *node = head; stack<int> st; int count = 0; while(node != NULL) { dout <<node->val <<"in stack" <<endl; st.push(node->val); count++; node = node->next; } // 为了效率我们静态vector开辟空间 vector<int> res(count); dout <<"count = " <<count <<endl; for(int i = 0; i < count && st.empty( ) != true; i++) { dout <<st.top() <<"in vector" <<endl; // 如果静态开辟vector不能使用push_back // 否则会在原来数据的基础上增加 //res.push_back(st.top( )); res[i] = st.top( ); st.pop( ); } return res; }};int __tmain( ){ ListNode list[4]; list[0].val = 1; list[0].next = &list[1]; list[1].val = 2; list[1].next = &list[2]; list[2].val = 3; list[2].next = &list[3]; list[3].val = 4; list[3].next = NULL; Solution solu; vector<int> res = solu.printListFromTailToHead(list); cout <<"there are " <<res.size( ) <<"datas in vector" <<endl; for(int i = 0; i < res.size( ); i++) { cout <<res[i] <<endl; } return 0;}
递归实现
递归在本质上就是一个栈结构,于是很自然地想到用递归来实现。要实现反过来输出链表,每访问到一个结点的时候,先递归输出它后面的结点,再输出该结点自身,这样链表的输出结构就反过来了。
算法流程如下
* 只要当前节点不为NULL,也就是链表没到头,就一直递归
* 在递归结束时,将元素压入
这样当递归结束进行返回时,会将递归栈中的数据依次压入vector中,而压入的顺序就是栈中的顺序,即从尾到头
class Solution{public: vector<int> printListFromTailToHead(struct ListNode* head) { vector<int> res; printListFromTailToHeadRecursion(head, res); return res; } void printListFromTailToHeadRecursion(struct ListNode* head, vector<int> &res) { if(head != NULL) { printListFromTailToHeadRecursion(head->next, res); res.push_back(head->val); } }};
上面用辅助函数的方法,每次都需要传递一个vector,很麻烦啊,我们可以直接用一个成员变量来存储
class Solution{public: vector<int> res; vector<int> printListFromTailToHead(struct ListNode* head) { if(head != NULL) { printListFromTailToHead(head->next); res.push_back(head->val); } return res; }};
- 剑指Offer--005-从尾到头打印链表
- 《剑指offer》005-从尾到头打印链表
- 剑指offer:5-从尾到头打印链表
- [剑指Offer]7.从尾到头打印链表
- 剑指offer:从尾到头打印链表
- 从尾到头打印链表--《剑指offer》
- 剑指Offer:从尾到头打印链表
- 【剑指offer】从尾到头打印链表
- 【剑指offer】Q5:从尾到头打印链表
- 剑指Offer之从尾到头打印链表
- 剑指offer系列源码-从尾到头打印链表
- 剑指offer 05: 从尾到头打印链表
- 剑指offer--从尾到头打印链表
- 剑指offer-5 从尾到头打印链表
- 剑指Offer之 - 从尾到头打印链表
- 剑指offer 5 -从尾到头打印链表
- 剑指offer: 从尾到头打印链表(链表)
- 《剑指Offer》面试题:从尾到头打印链表
- java多线程深入理解
- 图片轮播器 部分自用
- 新人小窝
- android 基础知识
- 《Effective STL》学习笔记(第四部分)
- 剑指Offer--005-从尾到头打印链表
- lintcode: Maximum Subarray
- poj天梯300题
- Java 浅谈输入输出流
- 计算字符串最后一个单词的长度,单词以空格隔开
- js获取url中传递的参数
- BroadcastReceiver
- eclipse错误:发现了以元素 ‘d:skin’ 开头的无效内容。此处不应含有子元素。
- kvm 虚拟化 virsh,virt-manager 删除虚拟机