这个是高频的面试题,今天总结了一些。反转链表用三个指针实现,返回新链表的头节点;而从尾到头打印,应用栈实现,返回vector整个链表。

  1. //题目描述
  2. //
  3. //输入一个链表,反转链表后,输出链表的所有元素。
  4.  
  5. struct ListNode
  6. {
  7. int val;
  8. struct ListNode *next;
  9. ListNode(int x) :val(x), next(nullptr){}
  10. };
  11.  
  12. //思路
  13. //在反转链表的时候,我们很容易想到让当前结点的next指向前一个结点,
  14. //但是这样做了之后这个节点原本next所指的结点就找不回了,所以每次我们都要保存新的前一结点,
  15. //当前结点和下一结点三个指针,只要下一结点为空,那么我们就到了原本结点的尾部,这时正是新链表的头部
  16. class Solution {
  17. public:
  18. ListNode* ReverseList(ListNode* pHead) {
  19.  
  20. ListNode *current = pHead;
  21. ListNode *pre = nullptr;
  22. ListNode *pNewNode = nullptr;
  23. if (pHead == nullptr)
  24. {
  25. return nullptr;
  26. }
  27. while (current != nullptr) //当前结点不为空
  28. {
  29. ListNode *pnext = current->next; //当前结点的后继
  30. if (pnext == nullptr)
  31. {
  32. pNewNode = current; //最后结点,即反转链表的头节点
  33. }
  34. current->next = pre; //当前结点的后继转为前驱
  35. pre = current; //前驱转为当前结点
  36. current = pnext; //当前结点向后移
  37. }
  38. return pNewNode;
  39. }
  40. };
  41.  
  42. //1、三个指针在链表上同时滑动,比较容易想到但是编码略复杂
  43. class Solution {
  44. public:
  45. ListNode* ReverseList(ListNode* pHead) {
  46. if (pHead == nullptr) return nullptr;
  47. if (pHead->next == nullptr) return pHead;
  48.  
  49. ListNode *pBefore = pHead, *p = pHead->next, *pAfter = p->next;
  50. while (pAfter) {
  51. p->next = pBefore; // reverse
  52. pBefore = p;
  53. p = pAfter;
  54. pAfter = pAfter->next;
  55. }
  56. p->next = pBefore; //完成最后一个结点的前驱
  57. pHead->next = nullptr; //尾结点后继为空
  58. return p;
  59. }
  60. };
  61.  
  62. //2、从原链表的头部一个一个取节点并插入到新链表的头部
  63. class Solution {
  64. public:
  65. ListNode* ReverseList(ListNode* pHead) {
  66. if (pHead == nullptr) return nullptr;
  67. ListNode* head = pHead;
  68. pHead = pHead->next;
  69. head->next = nullptr; //此时的head为尾结点
  70. while (pHead) {
  71. ListNode *next = pHead->next;
  72. pHead->next = head;
  73. head = pHead; //
  74. pHead = next;
  75. }
  76. return head;
  77. }
  78. };
  79.  
  80. //使用一个栈来解决问题,C++
  81.  
  82. #include<stack>
  83. using namespace std;
  84. class Solution {
  85. public:
  86. ListNode* ReverseList(ListNode* pHead) {
  87. if (pHead == nullptr || pHead->next == nullptr)
  88. {
  89. return pHead;
  90. }
  91. ListNode * p = pHead;
  92. ListNode * newHead;
  93. stack<ListNode *> stack1;
  94. while (p->next != NULL)
  95. {
  96. stack1.push(p);
  97. p = p->next;
  98. }
  99. newHead = p;
  100. while (!stack1.empty())
  101. {
  102. p->next = stack1.top();
  103. p = p->next;
  104. stack1.pop();
  105. }
  106. p->next = NULL;
  107. return newHead;
  108. }
  109. };
  110.  
  111. //题目描述
  112. //
  113. //输入一个链表,从尾到头打印链表每个节点的值。
  114. //输入描述 :
  115. //输入为链表的表头
  116. //
  117. //
  118. //输出描述 :
  119. //输出为需要打印的“新链表”的表头
  120. #include<vector>
  121. class Solution {
  122. public:
  123. vector<int> printListFromTailToHead(struct ListNode* head) {
  124.  
  125. //std::stack<ListNode*> nodes;
  126.  
  127. // ListNode *pNode = head;
  128. // while(pNode != NULL)
  129. // {
  130. // nodes.push(head);
  131. // head = head->next;
  132. // }
  133.  
  134. // while(!nodes.empty())
  135. // {
  136. // head = nodes.top();
  137. // printf("%d\t" ,head->val);
  138. // nodes.pop();
  139. // }
  140.  
  141. vector<int> dev1;
  142. if (head != NULL)
  143. {
  144. if (head->next != NULL)
  145. {
  146. dev1 = printListFromTailToHead(head->next);
  147. }
  148. dev1.push_back(head->val);
  149. }
  150. return dev1;
  151.  
  152. }
  153. };
  154.  
  155. class Solution {
  156. public:
  157. vector<int> printListFromTailToHead(struct ListNode* head) {
  158. //利用栈的逆序输出特性
  159. stack<int> stack;
  160. vector<int> vector;
  161. struct ListNode *p = head;
  162. if (head != NULL) {
  163. stack.push(p->val);
  164. while ((p = p->next) != NULL) {
  165. stack.push(p->val);
  166. }
  167. while (!stack.empty()) {
  168. vector.push_back(stack.top());
  169. stack.pop();
  170. }
  171. }
  172. return vector;
  173. }
  174.  
  175. };
  176.  
  177. /***
  178. *从原理上来说,借助栈会使得问题的解决思路非常简单明了。
  179. *注意函数的返回类型是int类型的vector
  180. */
  181. class Solution {
  182. public:
  183. vector<int> printListFromTailToHead(struct ListNode* head)
  184. {
  185. vector<int> vec; //声明一个vector存放Node的int类型的val值
  186. std::stack<ListNode *>nodes;
  187. ListNode *pNode = head;
  188. //遍历入栈
  189. while (pNode != NULL)
  190. {
  191. nodes.push(pNode); //遍历所有节点,将结点压入栈中
  192. pNode = pNode->next;
  193. }
  194. //遍历出栈
  195. while (!nodes.empty())
  196. {
  197. pNode = nodes.top(); //定义的结点指针始终指向栈顶,取出栈顶结点的val值存入到定义的vec中,然后弹出栈顶元素。由栈顶往栈底遍历
  198. vec.push_back(pNode->val);
  199. nodes.pop();
  200. }
  201. return vec; //返回值为int型的vector
  202. }
  203. };

offer--链表反转和从尾到头打印链表的更多相关文章

  1. 剑指Offer - 九度1511 - 从尾到头打印链表

    剑指Offer - 九度1511 - 从尾到头打印链表2013-11-29 21:08 题目描述: 输入一个链表,从尾到头打印链表每个节点的值. 输入: 每个输入文件仅包含一组测试样例.每一组测试案例 ...

  2. JS 剑指Offer(四) 从尾到头打印链表

    题目:输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回). 首先定义一下链表中的节点,关于链表这个数据结构在另外一篇文章中会详细讲 function ListNode(val) { t ...

  3. 剑指offer【03】- 从尾到头打印链表(4种实现方法)

    题目:从尾到头打印链表 考点:链表 题目描述:输入一个链表,按链表值从尾到头的顺序返回一个ArrayList. 法一:ArrayList头插法 /** * public class ListNode ...

  4. 【Offer】[6] 【从尾到头打印链表】

    题目描述 思路分析 Java代码 代码链接 题目描述 从尾到头打印链表,将其添加到ArrayList当中输出 思路分析 递归的思路 利用栈 Java代码 public class Offer006 { ...

  5. 剑指offer(3)从尾到头打印链表

    题目描述 输入一个链表,从尾到头打印链表每个节点的值. 题目分析 比较简单,主要注意下从尾到头,可以用栈可以用递归,我给出我比较喜欢的代码吧 代码 /* function ListNode(x){ t ...

  6. 【剑指Offer】3、从尾到头打印链表

      题目描述:   输入一个链表,按链表值从尾到头的顺序返回一个ArrayList.   解题思路:   (三种方法:借助栈.递归.列表的首位插入)   从头到尾打印链表比较简单,从尾到头很自然的可以 ...

  7. 剑指offer第二版-6.从尾到头打印链表

    描述:输入一个链表的头节点,从尾到头打印每个节点的值. 思路:从尾到头打印,即为“先进后出”,则可以使用栈来处理:考虑递归的本质也是一个栈结构,可递归输出. 考点:对链表.栈.递归的理解. packa ...

  8. 剑指offer(5)——从尾到头打印链表

    题目: 输入一个链表的头结点,从尾到头反过来打印出每个结点的值.结点定义如下: public class ListNode { int val; ListNode next = null; ListN ...

  9. 剑指Offer编程题3——从尾到头打印链表

    题目描述 输入一个链表,按链表值从尾到头的顺序返回一个ArrayList.   题目解析 方法1:建立两个vector,第一个用来存储正向访问的数据,第二个用来反向存储. /** * struct L ...

随机推荐

  1. istream, outstream使用及常见错误

    使用方法: 使用filebuf打开文件,并拷贝给istream/ostream. 如下面的例子中,实现读取并处理deseq文件夹下所有文件,输出到ostream fw. code: #include& ...

  2. IE6下position:fixed;兼容

    *html{ background-image:url(about:blank); background-attachment:fixed;}/*解决抖动问题*/ .backto-top{ width ...

  3. Android 如何设置默认语言

    前言          欢迎大家我分享和推荐好用的代码段~~ 声明          欢迎转载,但请保留文章原始出处:          CSDN:http://www.csdn.net        ...

  4. python列表推导式详解

    推导式是Python中很强大的.很受欢迎的特性,具有语言简洁,简化代码,速度快等优点.推导式包括:1.列表推导式2.字典推导式3.集合推导式4.嵌套列表推导式注意: 字典和集合推导是最近才加入到Pyt ...

  5. Android Touch(1)事件的传递流程(*)

    1,Activity,ViewGroup,View的关系 2,触摸事件 3,传递事件时的重要函数 4,事件传递流程参考图 5,其它参考资料 1,Activity,ViewGroup,View的关系 本 ...

  6. Android App接入微信开放平台注意事项

    一.Android第三方应用接入微信开放平台的注意事项: 1. 到微信开放平台官网申请正式的AppID(需通过审核),要填写包名.app签名的md5值.至于如何获取app签名信息,官方提供签名包apk ...

  7. 转: sqlserver常用sql语句,更改字段,建立唯一键,多个字段去重复等

    [sql] view plain copy print?在CODE上查看代码片派生到我的代码片 --修改字段类型: --alter table 表名 alter column 待修改字段名 待修改字段 ...

  8. 【英语】Bingo口语笔记(17) - 表示“感谢/不用客气“

  9. 【英语】Bingo口语笔记(36) - ʌn的发音

    同样音标 读音相同 找最有把握的一个词

  10. 转深入学习heritrix---体系结构(Overview of the crawler)

    Heritrix采用了模块化的设计,它由一些核心类(core classes)和可插件模块(pluggable modules)构成.核心类可以配置,但不能被覆盖,插件模块可以被由第三方模块取代. ( ...