diff --git a/notes/面试总结.md b/notes/面试总结.md index f7efa4e3..704ae7f1 100644 --- a/notes/面试总结.md +++ b/notes/面试总结.md @@ -4,6 +4,7 @@ * [3. 数组中重复的数字](#3-数组中重复的数字) * [4. 二维数组中的查找](#4-二维数组中的查找) * [5. 替换空格](#5-替换空格) +* [6. 从尾到头打印链表](#6-从尾到头打印链表) * [参考文献](#参考文献) @@ -334,6 +335,87 @@ print (target.replace(" ", "%20")) ``` +# 6. 从尾到头打印链表 + +[NowCoder](https://www.nowcoder.com/practice/d0267f7f55b3412ba93bd35cfa8e8035?tpId=13&tqId=11156&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking) + +## 题目描述 + +输入链表的第一个节点,从尾到头反过来打印出每个结点的值。 + +

+ +## 解题思路 + +### 使用栈 + +```java +public ArrayList printListFromTailToHead(ListNode listNode) { + Stack stack = new Stack<>(); + while (listNode != null) { + stack.add(listNode.val); + listNode = listNode.next; + } + ArrayList ret = new ArrayList<>(); + while (!stack.isEmpty()) + ret.add(stack.pop()); + return ret; +} +``` + +### 使用递归 + +```java +public ArrayList printListFromTailToHead(ListNode listNode) { + ArrayList ret = new ArrayList<>(); + if (listNode != null) { + ret.addAll(printListFromTailToHead(listNode.next)); + ret.add(listNode.val); + } + return ret; +} +``` + +### 使用头插法 + +利用链表头插法为逆序的特点。 + +头结点和第一个节点的区别: + +- 头结点是在头插法中使用的一个额外节点,这个节点不存储值; +- 第一个节点就是链表的第一个真正存储值的节点。 + +```java +public ArrayList printListFromTailToHead(ListNode listNode) { + // 头插法构建逆序链表 + ListNode head = new ListNode(-1); + while (listNode != null) { + ListNode memo = listNode.next; + listNode.next = head.next; + head.next = listNode; + listNode = memo; + } + // 构建 ArrayList + ArrayList ret = new ArrayList<>(); + head = head.next; + while (head != null) { + ret.add(head.val); + head = head.next; + } + return ret; +} +``` + +```python +def printListFromTailToHead(self, listNode): + # write code here + l = list() + while listNode: + l.append(listNode.val) + listNode = listNode.next + l.reverse() + return l +``` # 参考文献