題目描述:
輸入一個鏈表,按鏈表值從尾到頭的順序返回一個ArrayList。
解題思路:
(三種方法:借助棧、遞歸、列表的首位插入)
從頭到尾打印鏈表比較簡單,從尾到頭很自然的可以想到先將鏈表進行反轉,然后再打印。但是,通常我們不希望改變原鏈表的結構,這是一個只讀操作。
因此,我們進一步分析,可以發現排在后面的先輸出,這是一個典型的“后入先出”的思想,因此很自然的可以想到用棧來實現,每遍歷一個結點,可以將其壓入棧中,遍歷結束后再逐個彈棧,將結點值存入ArrayList,這樣就實現了從尾到頭的打印。
更進一步,既然想到了用棧,那一定可以通過遞歸來實現。每訪問到一個結點,先遞歸輸出其后的結點,在輸出該結點自身即可。
另外,當我們使用Java或者python語言時,有一種比較巧妙的方法就是使用列表的插入方法,每次插入數據,都總是插入到首位,這樣得到的List就是從尾到頭的鏈表序列。
編程實現(Java):
//方法一:借助棧的后入先出實現
public ArrayList<Integer> printListFromTailToHead(ListNode listNode){
ArrayList<Integer> list=new ArrayList<>();
if(listNode==null)
return list;
ListNode head=listNode;
Stack<ListNode> 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<Integer> printListFromTailToHead(ListNode listNode) {
ArrayList<Integer> list=new ArrayList<>();
getNext(listNode,list);
return list;
}
public void getNext(ListNode listNode,ArrayList<Integer> list){
if(listNode!=null){
getNext(listNode.next,list); //先遞歸輸出其后的結點
list.add(listNode.val); //再輸出自身
}
}
//方法三:列表的首位插入
public ArrayList<Integer> printListFromTailToHead(ListNode listNode){
ArrayList<Integer> list=new ArrayList<>();
if(listNode==null)
return list;
ListNode head=listNode;
while(head!=null){
list.add(0,head.val); //每次插入數據,都總是插入到首位
head=head.next;
}
return list;
}