紧接着又练习了一个链表的操作——从尾到头打印链表。
牛客网AC地址:http://www.nowcoder.com/books/coding-interviews/d0267f7f55b3412ba93bd35cfa8e8035?rp=1
《剑指offer》面试题5:从尾到头打印链表
题目:输入一个链表的头结点,从尾到头反过来打印出每个结点的值。
链表的节点定义如下:
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
查看牛客网给出的一些代码:
import java.util.ArrayList;
public class Solution {
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
}
}
思路:
这里,就借助ArrayList来实现,由于给出的是单链表,所以遍历的时候,得到的是正序;
但是ArrayList可认为是“数组”,可以倒序遍历。
所以,我们一边遍历单链表,一边存入一个临时的ArrayList;然后倒序遍历这个临时的ArrayList,将数据转存过来,这样就相当于倒序遍历了。
AC代码:(注意:有一点觉得很奇怪,之前放上了打印数据的代码结果一直是答案错误,去掉之后就通过了。——下面注释掉的代码)
public class Solution {
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) { // 返回新链表的头结点
ArrayList<Integer> newHead = new ArrayList<Integer>();
ArrayList<Integer> temp = new ArrayList<Integer>();
while (listNode != null) { // 遍历链表将节点的val放入ArrayList
temp.add(listNode.val);
listNode = listNode.next;
}
// 遍历ArrayList (倒叙遍历),将数据加入到newHead中
for (int i = temp.size() - 1; i >= 0; --i) {
newHead.add(temp.get(i));
/*if (i == 0) {
System.out.println(temp.get(i));
} else {
System.out.print(temp.get(i) + ",");
}*/
}
//System.out.println();
return newHead;
}
}
下面补充,《剑指offer》上,使用栈和递归实现的思路。
使用栈的情况:
题目要求,从尾到头遍历单链表。也就是第一个遍历到的节点要最后一个输出,最后一个遍历到的节点第一个输出。这就是典型的“后进先出”,由此可借助栈实现这种顺序。
每经过一个结点的时候,把该结点放到一个栈中。
当遍历完整个链表后,再从栈顶开始逐个输出结点的值,此时输出的结点的顺序已经反转过来了。
void PrintListReversingly_Iteratively(ListNode* pHead) {
std::stack<ListNode*> nodes;
ListNode* pNode = pHead;
while (pNode != NULL) {
nodes.push(pNode);
pNode = pNode->m_pNext;
}
while (!nodes.empty()) {
pNode = nodes.top();
printf("%d\t", pNode->m-nValue);
nodes.pop();
}
}
其中,单向链表的结点定义如下:
struct ListNode {
int m_nValue;
ListNode* m_pNext;
};
使用递归:
递归在本质上就是一个栈结构。
要实现反过来输出链表,我们每访问到一个结点的时候,先递归输出它后面的结点,再输出该结点自身,这样链表的输出结果就反过来了。
void PrintListReversingly_Recursively(ListNode* pHead) {
if (pHead != NULL) {
if (pHead->m_pNext != NULL) {
PrintListReversingly_Recursively(pHead->m_pNext);
}
printf("%d\t", pHead->m_nValue);
}
}
但有个问题:当链表非常长的时候,就会导致函数调用的层级很深,从而有可能导致函数调用栈溢出。