程序员社区

剑指Offer系列(java版,详细解析)06.从尾到头打印链表

题目描述

剑指 Offer 06. 从尾到头打印链表

难度简单108

输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。

示例 1:

输入:head = [1,3,2]
输出:[2,3,1]

限制:

0 <= 链表长度 <= 10000

测试用例

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

题目考点

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

解题思路

使用头插法将链表反转

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

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

使用栈

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

使用递归

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

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

使用 Collections.reverse()

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

自己解题

class problem06 {
   
      public class ListNode {
   
     int val;
      ListNode next;
      ListNode(int x) {
    val = x; }
  }
    public int[] reversePrint(ListNode head) {
   
        if(head==null)
            return new int[0];
        Stack<Integer> stack = new Stack<>();
        while(head.next!=null){
   
            stack.push(head.val);
            head=head.next;
        }
        stack.push(head.val);
        int size = stack.size();
        int[] res = new int[size];
        for (int i = 0; i<size; i++) {
   
            res[i]=stack.pop();
        }
        return res;
    }
}

解题缺陷:

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

参考解题

使用头插法将链表反转

/** * 从尾到头打印链表 */
public class Solution1 {
   
    /** * @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;
    }
}

使用栈

/** * 从尾到头打印链表 */
public class Solution2 {
   
   /** * @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;
   }
}

使用递归

class Solution {
   
    ArrayList<Integer> tmp = new ArrayList<Integer>();
    public int[] reversePrint(ListNode head) {
   
        recur(head);
        int[] res = new int[tmp.size()];
        for(int i = 0; i < res.length; i++)
            res[i] = tmp.get(i);
        return res;
    }
    void recur(ListNode head) {
   
        if(head == null) return;
        recur(head.next);
        tmp.add(head.val);
    }
}

使用 Collections.reverse()

/** * 从尾到图打印链表 * */
public class Solution4 {
   
    /** * @Author rex */
    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;
    }
}
赞(0) 打赏
未经允许不得转载:IDEA激活码 » 剑指Offer系列(java版,详细解析)06.从尾到头打印链表

一个分享Java & Python知识的社区