题目描述:
输入一个链表,按链表值从尾到头的顺序返回一个arraylist。
解题思路:
(三种方法:借助栈、递归、列表的首位插入)
从头到尾打印链表比较简单,从尾到头很自然的可以想到先将链表进行反转,然后再打印。但是,通常我们不希望改变原链表的结构,这是一个只读操作。
因此,我们进一步分析,可以发现排在后面的先输出,这是一个典型的“后入先出”的思想,因此很自然的可以想到用栈来实现,每遍历一个结点,可以将其压入栈中,遍历结束后再逐个弹栈,将结点值存入arraylist,这样就实现了从尾到头的打印。
更进一步,既然想到了用栈,那一定可以通过递归来实现。每访问到一个结点,先递归输出其后的结点,在输出该结点自身即可。
另外,当我们使用java或者python语言时,有一种比较巧妙的方法就是使用列表的插入方法,每次插入数据,都总是插入到首位,这样得到的list就是从尾到头的链表序列。
代码实现(c )
/**
* struct listnode {
* int val;
* struct listnode *next;
* listnode(int x) :
* val(x), next(null) {
* }
* };
*/
class solution {
public:
vector printlistfromtailtohead(listnode* head) {
stack nodes;
vector result;
listnode* node = head;
while(node != null){
nodes.push(node->val);
node = node->next;
}
while(!nodes.empty()){
result.push_back(nodes.top());
nodes.pop();
}
return result;
}
};
代码实现(java)
//方法一:借助栈的后入先出实现
public arraylist printlistfromtailtohead(listnode listnode){
arraylist list=new arraylist<>();
if(listnode==null)
return list;
listnode head=listnode;
stack stack=new stack<>();
while(head!=null){ //依次压入栈中
stack.push(head);
head=head.next;
}
while(!stack.isempty()){ //逐个弹栈
listnode temp=stack.pop();
list.add(temp.val);
}
return list;
}
//方法二:递归实现
public arraylist printlistfromtailtohead(listnode listnode) {
arraylist list=new arraylist<>();
getnext(listnode,list);
return list;
}
public void getnext(listnode listnode,arraylist list){
if(listnode!=null){
getnext(listnode.next,list); //先递归输出其后的结点
list.add(listnode.val); //再输出自身
}
}
//方法三:列表的首位插入
public arraylist printlistfromtailtohead(listnode listnode){
arraylist list=new arraylist<>();
if(listnode==null)
return list;
listnode head=listnode;
while(head!=null){
list.add(0,head.val); //每次插入数据,都总是插入到首位
head=head.next;
}
return list;
}