您的位置:首页 > 编程语言 > C语言/C++

《剑指offer》面试题6:从尾到头打印链表(C++实现)

2019-05-21 20:37 417 查看

《剑指offer》面试题6:从尾到头打印链表(C++实现)

题目描述

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

思路一:反转链表后再读出

看到这道题我们很自然而然的就会想到,既然让我们从尾到头进行一个打印,那很明显,我们可以先把链表进行反转,再从头到尾打印一遍即可。

/**
*  struct ListNode {
*        int val;
*        struct ListNode *next;
*        ListNode(int x) :
*              val(x), next(NULL) {
*        }
*  };
*/
class Solution {
public:
vector<int> printListFromTailToHead(ListNode* head) {
vector<int> result;
//反转链表
ListNode* pre = NULL;
ListNode* cur = head;
while(cur != NULL){
ListNode* next = cur->next;//存放当前节点的下一节点
cur->next = pre;//cur从指向next,改为指向pre
pre = cur ;//右移
cur = next;//下一节点赋值给当前节点
}

//反转完成时,
while(pre!= nullptr){
result.push_back(pre->val);
pre = pre->next;
}
return result;
}

};

思路二:用栈去实现

如果我们不希望对于输入的数据进行修改。那我们可以在从头到尾遍历链表的时候,用栈记录下当前节点的值。当完成链表的遍历的时候,然后根据栈先进后出的特性,从栈顶开始逐个输出节点的值,那么就实现了从尾到头打印链表的目的。

/**
*  struct ListNode {
*        int val;
*        struct ListNode *next;
*        ListNode(int x) :
*              val(x), next(NULL) {
*        }
*  };
*/
class Solution {
public:
vector<int> printListFromTailToHead(ListNode* head) {
stack<int> nodes;//存放节点的值
vector<int> result;
ListNode* pNode = head;

//用栈去记录数值
while(pNode!=nullptr){
nodes.push(pNode->val);
pNode = pNode->next;
}

//用vertor去读取从栈顶到栈底的元素
while(!nodes.empty()){
result.push_back(nodes.top());
nodes.pop();
}
return result;

思路三:递归实现

既然我们想到了用栈去实现这个函数,而递归的本质是一个栈的结构。所以我们很自然地又想到了用递归去实现。
思路就是,我们先输出当前节点的下一节点的值,再输出当前节点的值,即可完成。

/**
*  struct ListNode {
*        int val;
*        struct ListNode *next;
*        ListNode(int x) :
*              val(x), next(NULL) {
*        }
*  };
*/
/**
*  struct ListNode {
*        int val;
*        struct ListNode *next;
*        ListNode(int x) :
*              val(x), next(NULL) {
*        }
*  };
*/
class Solution {
public:
vector<int> result;
vector<int> printListFromTailToHead(ListNode* head) {
if(head != nullptr)
{
if(head->next != nullptr)
{
printListFromTailToHead(head->next);
}
result.push_back(head->val);

}
return result;

}
};

递归会一直执行到链表的最后一个节点,然后发现下一节点为空,不再进行调用,然后把当前节点的值添加进result之中。然后添加完后返回递归调用的上一级,添加它的上一个节点的值,依次类推,直到添加完成链表所有的值。

小结

思路一引起了输入的改变。
思路三递归的代码看上去很简洁,但是如果当链表非常长的时候,就会导致函数调用的层级很深,从而有可能导致函数调用栈溢出。
针对代码的鲁棒性,而言最好的是思路二。

参考文献

《剑指offer》

牛课网刷题链接link.

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: