offer--链表反转和从尾到头打印链表
这个是高频的面试题,今天总结了一些。反转链表用三个指针实现,返回新链表的头节点;而从尾到头打印,应用栈实现,返回vector整个链表。
//题目描述
//
//输入一个链表,反转链表后,输出链表的所有元素。
struct ListNode
{
int val;
struct ListNode *next;
ListNode(int x) :val(x), next(nullptr){}
};
//思路
//在反转链表的时候,我们很容易想到让当前结点的next指向前一个结点,
//但是这样做了之后这个节点原本next所指的结点就找不回了,所以每次我们都要保存新的前一结点,
//当前结点和下一结点三个指针,只要下一结点为空,那么我们就到了原本结点的尾部,这时正是新链表的头部
class Solution {
public:
ListNode* ReverseList(ListNode* pHead) {
ListNode *current = pHead;
ListNode *pre = nullptr;
ListNode *pNewNode = nullptr;
if (pHead == nullptr)
{
return nullptr;
}
while (current != nullptr) //当前结点不为空
{
ListNode *pnext = current->next; //当前结点的后继
if (pnext == nullptr)
{
pNewNode = current; //最后结点,即反转链表的头节点
}
current->next = pre; //当前结点的后继转为前驱
pre = current; //前驱转为当前结点
current = pnext; //当前结点向后移
}
return pNewNode;
}
};
//1、三个指针在链表上同时滑动,比较容易想到但是编码略复杂
class Solution {
public:
ListNode* ReverseList(ListNode* pHead) {
if (pHead == nullptr) return nullptr;
if (pHead->next == nullptr) return pHead;
ListNode *pBefore = pHead, *p = pHead->next, *pAfter = p->next;
while (pAfter) {
p->next = pBefore; // reverse
pBefore = p;
p = pAfter;
pAfter = pAfter->next;
}
p->next = pBefore; //完成最后一个结点的前驱
pHead->next = nullptr; //尾结点后继为空
return p;
}
};
//2、从原链表的头部一个一个取节点并插入到新链表的头部
class Solution {
public:
ListNode* ReverseList(ListNode* pHead) {
if (pHead == nullptr) return nullptr;
ListNode* head = pHead;
pHead = pHead->next;
head->next = nullptr; //此时的head为尾结点
while (pHead) {
ListNode *next = pHead->next;
pHead->next = head;
head = pHead; //
pHead = next;
}
return head;
}
};
//使用一个栈来解决问题,C++
#include<stack>
using namespace std;
class Solution {
public:
ListNode* ReverseList(ListNode* pHead) {
if (pHead == nullptr || pHead->next == nullptr)
{
return pHead;
}
ListNode * p = pHead;
ListNode * newHead;
stack<ListNode *> stack1;
while (p->next != NULL)
{
stack1.push(p);
p = p->next;
}
newHead = p;
while (!stack1.empty())
{
p->next = stack1.top();
p = p->next;
stack1.pop();
}
p->next = NULL;
return newHead;
}
};
//题目描述
//
//输入一个链表,从尾到头打印链表每个节点的值。
//输入描述 :
//输入为链表的表头
//
//
//输出描述 :
//输出为需要打印的“新链表”的表头
#include<vector>
class Solution {
public:
vector<int> printListFromTailToHead(struct ListNode* head) {
//std::stack<ListNode*> nodes;
// ListNode *pNode = head;
// while(pNode != NULL)
// {
// nodes.push(head);
// head = head->next;
// }
// while(!nodes.empty())
// {
// head = nodes.top();
// printf("%d\t" ,head->val);
// nodes.pop();
// }
vector<int> dev1;
if (head != NULL)
{
if (head->next != NULL)
{
dev1 = printListFromTailToHead(head->next);
}
dev1.push_back(head->val);
}
return dev1;
}
};
class Solution {
public:
vector<int> printListFromTailToHead(struct ListNode* head) {
//利用栈的逆序输出特性
stack<int> stack;
vector<int> vector;
struct ListNode *p = head;
if (head != NULL) {
stack.push(p->val);
while ((p = p->next) != NULL) {
stack.push(p->val);
}
while (!stack.empty()) {
vector.push_back(stack.top());
stack.pop();
}
}
return vector;
}
};
/***
*从原理上来说,借助栈会使得问题的解决思路非常简单明了。
*注意函数的返回类型是int类型的vector
*/
class Solution {
public:
vector<int> printListFromTailToHead(struct ListNode* head)
{
vector<int> vec; //声明一个vector存放Node的int类型的val值
std::stack<ListNode *>nodes;
ListNode *pNode = head;
//遍历入栈
while (pNode != NULL)
{
nodes.push(pNode); //遍历所有节点,将结点压入栈中
pNode = pNode->next;
}
//遍历出栈
while (!nodes.empty())
{
pNode = nodes.top(); //定义的结点指针始终指向栈顶,取出栈顶结点的val值存入到定义的vec中,然后弹出栈顶元素。由栈顶往栈底遍历
vec.push_back(pNode->val);
nodes.pop();
}
return vec; //返回值为int型的vector
}
};
offer--链表反转和从尾到头打印链表的更多相关文章
- 剑指Offer - 九度1511 - 从尾到头打印链表
剑指Offer - 九度1511 - 从尾到头打印链表2013-11-29 21:08 题目描述: 输入一个链表,从尾到头打印链表每个节点的值. 输入: 每个输入文件仅包含一组测试样例.每一组测试案例 ...
- JS 剑指Offer(四) 从尾到头打印链表
题目:输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回). 首先定义一下链表中的节点,关于链表这个数据结构在另外一篇文章中会详细讲 function ListNode(val) { t ...
- 剑指offer【03】- 从尾到头打印链表(4种实现方法)
题目:从尾到头打印链表 考点:链表 题目描述:输入一个链表,按链表值从尾到头的顺序返回一个ArrayList. 法一:ArrayList头插法 /** * public class ListNode ...
- 【Offer】[6] 【从尾到头打印链表】
题目描述 思路分析 Java代码 代码链接 题目描述 从尾到头打印链表,将其添加到ArrayList当中输出 思路分析 递归的思路 利用栈 Java代码 public class Offer006 { ...
- 剑指offer(3)从尾到头打印链表
题目描述 输入一个链表,从尾到头打印链表每个节点的值. 题目分析 比较简单,主要注意下从尾到头,可以用栈可以用递归,我给出我比较喜欢的代码吧 代码 /* function ListNode(x){ t ...
- 【剑指Offer】3、从尾到头打印链表
题目描述: 输入一个链表,按链表值从尾到头的顺序返回一个ArrayList. 解题思路: (三种方法:借助栈.递归.列表的首位插入) 从头到尾打印链表比较简单,从尾到头很自然的可以 ...
- 剑指offer第二版-6.从尾到头打印链表
描述:输入一个链表的头节点,从尾到头打印每个节点的值. 思路:从尾到头打印,即为“先进后出”,则可以使用栈来处理:考虑递归的本质也是一个栈结构,可递归输出. 考点:对链表.栈.递归的理解. packa ...
- 剑指offer(5)——从尾到头打印链表
题目: 输入一个链表的头结点,从尾到头反过来打印出每个结点的值.结点定义如下: public class ListNode { int val; ListNode next = null; ListN ...
- 剑指Offer编程题3——从尾到头打印链表
题目描述 输入一个链表,按链表值从尾到头的顺序返回一个ArrayList. 题目解析 方法1:建立两个vector,第一个用来存储正向访问的数据,第二个用来反向存储. /** * struct L ...
随机推荐
- flex 4 布局样式
Flex 4 样式与布局 第一篇 Flex 4 与自定义布局(Layout) Flex 4/Spark组件架构的新功能之一是可以定制一个容器的布局而不必改变容器本身.您需要做的就是定义一个自定义布局. ...
- VIM的配置文件(vimrc)在哪里?【Win7】
如果你使用VIM有一段时间的话,你会想要修改它的一些配置,例如默认显示行号.在哪改呢? 答案是:vimrc 那这个配置文件在哪呢? 打开你的vi,在命令模式下,输入[:version],会看到如下图所 ...
- 每天一个小算法(Shell Sort2)
希尔排序: 伪代码: input: an array a of length n with array elements numbered 0 to n − 1 inc ← round(n/2) wh ...
- 15.导入网表及status介绍[原创]
一.导入网表 在导入网表之前你的封装需确认是在你的封装路径下 建立Board工程后: ① ② ③ ④放置器件 ⑤ (切记,封装路径一定要添加) 二.status介绍 --- (常用) -------- ...
- poj - 2431 Expedition (优先队列)
http://poj.org/problem?id=2431 你需要驾驶一辆卡车做一次长途旅行,但是卡车每走一单位就会消耗掉一单位的油,如果没有油就走不了,为了修复卡车,卡车需要被开到距离最近的城镇, ...
- file的这几个取得path的方法各有不同,下边说说详细的区别
html, body { font-size: 15px; } body { font-family: Helvetica, "Hiragino Sans GB", 微软雅黑, & ...
- java 反编译插件 JD-Eclipse 和 JD-IntelliJ
去官网 : http://jd.benow.ca/ 找到 JD-Eclipse 和 JD-IntelliJ,下载,前者安在eclipse上,后者安在as上.
- php面试题整理
PHP经典面试题:(不断跟进补充中...) 1.用PHP打印出前一天的时间格式是2009-02-10 22:21:21(2分) echo date('Y-m-d H:i:s', strtotime(' ...
- JavaScript高级编程(一)
书中第2章,在HTML中使用JavaScript摘要总结 2.1 <script>元素 <script>中的5个属性:charset:可选.表示通过src属性指定的代码的字符集 ...
- Javascript学习-闭包
看的这篇 http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html 各种专业文献上的"闭包" ...