剑指offer之面试题5:从尾到头打印链表

来源:互联网 发布:阿里社招在线编程 编辑:程序博客网 时间:2024/05/06 13:24

题目描述

输入一个链表,从尾到头打印链表每个节点的值。
输入描述:

输入为链表的表头

输出描述:

输出为需要打印的“新链表”的表头

思路1:new一个临时的ArrayList(temp),遍历一遍链表,将链表的每个值顺序放进temp中;new一个新的ArrayList(list),遍历一遍temp,通过list.get(list.size()-1-i)获取倒序的链表元素,并顺序放进list中。最后返回list。

下面贴出根据这一思路编写的代码,已在牛客OJ提交成功

/***    public class ListNode {*        int val;*        ListNode next = null;**        ListNode(int val) {*            this.val = val;*        }*    }**/import java.util.ArrayList;public class Solution {    public static ArrayList<Integer> printListFromTailToHead(ListNode listNode) {        ArrayList<Integer> temp=new ArrayList<Integer>();        //put list to new list        while(listNode!=null){            temp.add(listNode.val);            listNode=listNode.next;        }        ArrayList<Integer> list=new ArrayList<Integer>();        for(int i=0;i<temp.size();i++){            list.add(temp.get(temp.size()-i-1));        }        return list;    }    public static void main(String[] args){        ArrayList list=new ArrayList();        list.add(new ListNode(1));        list.add(new ListNode(2));        list.add(new ListNode(3));        list.add(new ListNode(4));        list.add(new ListNode(5));        for(int i=0;i<list.size();i++){            ListNode listNode=(ListNode)list.get(i);            if(i+1<list.size()){                listNode.next=(ListNode)list.get(i+1);            }        }        ListNode root=(ListNode)list.get(0);        System.out.println(printListFromTailToHead(root));    }}

思路2:后进先出,这是栈的工作原理,所以可以考虑用栈来实现,扫描一个结点时,把该结点push进栈中,直到扫描完所有结点元素,然后通过pop逐个去除栈顶元素打印,则打印出的顺序就是从尾到头。

根据以上思路,贴出实现代码,牛客网OJ提交成功

/***    public class ListNode {*        int val;*        ListNode next = null;**        ListNode(int val) {*            this.val = val;*        }*    }**/import java.util.ArrayList;import java.util.Stack;public class Solution {    public static ArrayList<Integer> printListFromTailToHead(ListNode listNode) {        Stack<Integer> stack=new Stack<Integer>();        while(listNode!=null){            stack.push(listNode.val);            listNode=listNode.next;        }        ArrayList<Integer> list=new ArrayList<Integer>();        while(!stack.empty()){            list.add(stack.pop());        }        return list;    }    public static void main(String[] args){        ArrayList list=new ArrayList();        list.add(new ListNode(1));        list.add(new ListNode(2));        list.add(new ListNode(3));        list.add(new ListNode(4));        list.add(new ListNode(5));        for(int i=0;i<list.size();i++){            ListNode listNode=(ListNode)list.get(i);            if(i+1<list.size()){                listNode.next=(ListNode)list.get(i+1);            }        }        ListNode root=(ListNode)list.get(0);        System.out.println(printListFromTailToHead(root));    }}

查看Stack的API,会发现栈的实现推荐使用ArrayDeque。

Deque 接口及其实现提供了 LIFO 堆栈操作的更完整和更一致的 set,应该优先使用此 set,而非此类。例如:    Deque<Integer> stack = new ArrayDeque<Integer>();
Deque 接口的大小可变数组的实现。数组双端队列没有容量限制;它们可根据需要增加以支持使用。它们不是线程安全的;在没有外部同步时,它们不支持多个线程的并发访问。禁止 null 元素。此类很可能在用作堆栈时快于 Stack,在用作队列时快于 LinkedList。

在不考虑线程安全的情况下,用ArrayDeque实现从尾到头打印链表的代码如下,在牛客OJ提交成功

/***    public class ListNode {*        int val;*        ListNode next = null;**        ListNode(int val) {*            this.val = val;*        }*    }**/import java.util.ArrayList;import java.util.ArrayDeque;public class Solution {    public static ArrayList<Integer> printListFromTailToHead(ListNode listNode) {        ArrayDeque<Integer> stack=new ArrayDeque<Integer>();        while(listNode!=null){            stack.push(listNode.val);            listNode=listNode.next;        }        ArrayList<Integer> list=new ArrayList<Integer>();        while(!stack.isEmpty()){            list.add(stack.pop());        }        return list;    }    public static void main(String[] args){        ArrayList list=new ArrayList();        list.add(new ListNode(1));        list.add(new ListNode(2));        list.add(new ListNode(3));        list.add(new ListNode(4));        list.add(new ListNode(5));        for(int i=0;i<list.size();i++){            ListNode listNode=(ListNode)list.get(i);            if(i+1<list.size()){                listNode.next=(ListNode)list.get(i+1);            }        }        ListNode root=(ListNode)list.get(0);        System.out.println(printListFromTailToHead(root));    }}

思路3:既然可以用栈实现,而递归本质上就是一个栈,故想到用递归实现。遍历链表结点,先打印结点后面的结点,在打印该结点。
用递归的思想实现代码如下,已被牛客网AC

/***    public class ListNode {*        int val;*        ListNode next = null;**        ListNode(int val) {*            this.val = val;*        }*    }**/import java.util.ArrayList;public class Solution {    public static ArrayList<Integer> printListFromTailToHead(ListNode listNode) {        ArrayList<Integer> list=new ArrayList<Integer>();        if(listNode!=null){            if(listNode.next!=null){                list=printListFromTailToHead(listNode.next);            }            //System.out.print(listNode.val+" ");            list.add(listNode.val);        }        return list;    }    public static void main(String[] args){        ArrayList list=new ArrayList();        //ListNode node=new ListNode();        list.add(new ListNode(1));        list.add(new ListNode(2));        list.add(new ListNode(3));        list.add(new ListNode(4));        list.add(new ListNode(5));        for(int i=0;i<list.size();i++){            ListNode listNode=(ListNode)list.get(i);            if(i+1<list.size()){                listNode.next=(ListNode)list.get(i+1);            }        }        ListNode root=(ListNode)list.get(0);        //System.out.println(root.next.val);        //printListFromTailToHead(root);        System.out.println(printListFromTailToHead(root));    }}
0 0
原创粉丝点击