Skip to content

Latest commit

 

History

History
192 lines (176 loc) · 4.95 KB

从尾到头打印链表.md

File metadata and controls

192 lines (176 loc) · 4.95 KB

题目描述

输入链表的第一个节点,从尾到头反过来打印出每个结点的值。

链表节点定义如下:

public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
    ListNode(){}
}

测试用例

  • 功能测试(输入的链表有多个节点;输入的链表只有一个节点)。
  • 特殊输入测试(输入的链表头节点为空)

题目考点

  • 考查应聘者对单向链表的理解和编程能力。
  • 考查应聘者对循环、递归和栈3个相互关联的概念的理解。

解题思路

使用头插法将链表反转

当链表反转过后,每个节点的值就可以从头到尾输出了。

PS: 在面试中,如果我们打算修改输入的数据,则最好先问面试官是否允许修改。

使用栈

每经过一个节点的时候,把该节点放到栈中。当遍历完整个链表后,再从栈顶开始逐个输出节点的值。

使用递归

递归在本质上就是一个栈结构。 我们每次访问到一个节点,先递归输入它后面的节点,在输入该节点本身。

PS: 当链表非常长的时候,就会导致函数的层级很深,从而有可能导致栈溢出。

使用 Collections.reverse()

从头到尾遍历链表,每次访问到一个节点,将值取出放入ArrayList,然后利用Collections.reverse()将数组的值反转。

自己解题

/**
 * 从尾到头打印链表
 * @Author rex
 * 2018/6/10
 */
public class Solution {
    /**
     * @Author rex
     * @Date 2018/6/10 下午8:09
     * @Description 从尾到头打印链表
     */
    public static ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        ArrayList<Integer> result = new ArrayList<Integer>();
        if (listNode == null) {
            return result;
        }
        List<Integer> list = new ArrayList<Integer>();

        while(listNode != null){
            list.add(listNode.val);
            listNode = listNode.next;
        }
        for(int i = list.size()-1; i >= 0; i--) {
            result.add(list.get(i));
        }
        return result;
    }
}

解题缺陷:

  1. 后面List反转部分可以使用Collections.reverse()直接反转。

参考解题

使用头插法将链表反转

/**
 * 从尾到头打印链表
 * @Author rex
 * 2018/6/10
 */
public class Solution1 {
    /**
     * @Author rex
     * @Date 2018/6/10 下午8:09
     * @Description 从尾到头打印链表(使用头插法将链表反转)
     */
    public static ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        ArrayList<Integer> result = new ArrayList<Integer>();

        if (listNode == null) {
            return result;
        }
        ListNode head = new ListNode();
        while (listNode != null) {
            ListNode temp = listNode.next;
            listNode.next = head.next;
            head.next = listNode;
            listNode = temp;
        }
        head = head.next;
        while (head != null) {
            result.add(head.val);
            head = head.next;
        }
        return result;
    }
}

使用栈

/**
* 从尾到头打印链表
* @Author rex
* 2018/6/10
*/
public class Solution2 {
   /**
    * @Author rex
    * @Date 2018/6/10 下午8:09
    * @Description 从尾到头打印链表(使用栈)
    */
   public static ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
       ArrayList<Integer> result = new ArrayList<Integer>();

       Stack<ListNode> stack = new Stack<>();
       while (listNode != null) {
           stack.push(listNode);
           listNode = listNode.next;
       }
       while (! stack.empty()) {
           result.add(stack.pop().val);
       }
       return result;
   }
}

使用递归

/**
 * 从尾到图打印链表
 *
 * @Author rex
 * 2018/6/10
 */
public class Solution3 {
    /**
     * @Author rex
     * @Date 2018/6/10 下午8:09
     * @Description 从尾到头打印链表(使用递归)
     */
    public static ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        ArrayList<Integer> result = new ArrayList<Integer>();

        if (listNode != null) {
            result.addAll(printListFromTailToHead(listNode.next));
            result.add(listNode.val);
        }
        return result;
    }
}

使用 Collections.reverse()

/**
 * 从尾到图打印链表
 *
 * @Author rex
 * 2018/6/10
 */
public class Solution4 {
    /**
     * @Author rex
     * @Date 2018/6/10 下午8:09
     * @Description 从尾到头打印链表(使用递归)
     */
    public static ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        ArrayList<Integer> result = new ArrayList<Integer>();
        if (listNode == null) {
            return result;
        }

        while (listNode != null) {
            result.add(listNode.val);
            listNode = listNode.next;
        }
        Collections.reverse(result);
        return result;
    }
}