从尾到头打印链表——剑指Offer

题目描述

输入一个链表,按链表从尾到头的顺序返回一个ArrayList。

解题思路

使用递归

如传入1->2->3,则需返回3,2,1。根据递归的压栈弹栈,可通过递归函数实现从尾到头将链表中的值add到ArrayList中。

/**
*    public class ListNode {
*        int val;
*        ListNode next = null;
*
*        ListNode(int val) {
*            this.val = val;
*        }
*    }
*
*/
import java.util.ArrayList;
public class Solution {
    ArrayList<Integer> ret=new ArrayList<>();
    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        //如果当前节点不为空
        if(listNode!=null){
            //递归传入当前节点的next
            printListFromTailToHead(listNode.next);
            //当递归结束后以递归出栈顺序将值add到ArrayList。起到逆序的作用。
            ret.add(listNode.val);
        }
        return ret;
    }
}

使用头插法

使用头插法可以得到一个逆序的链表。

头结点和第一个节点的区别:

  • 头结点是在头插法中使用的一个额外节点,这个节点不存储值;
  • 第一个节点就是链表的第一个真正存储值的节点。
import java.util.ArrayList;
public class Solution {
    ArrayList<Integer> ret=new ArrayList<>();
    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        //头插法构建逆序链表
        ListNode head=new ListNode(-1);
        while(listNode != null){
            //记录当前节点的next
            ListNode memo = listNode.next;
            //将当前节点的next指向head的next(从第二个节点开始就实现了逆序,指向了前一个节点)
            listNode.next = head.next;
            //head的next指向当前节点
            head.next = listNode;
            //listNode赋值为next,进入下一次循环
            listNode = memo;
        }
        //head的next开始为有效值
        head=head.next;
        //依次将链表值add到ArrayList中
        while(head != null){
            ret.add(head.val);
            head=head.next;
        }
        return ret;
    }
}

使用栈

栈具有后进先出的特点,在遍历链表时将值按顺序放入栈中,最后出栈的顺序即为逆序。

import java.util.ArrayList;
import java.util.Stack;
public ArrayList<Integer> printListFromTailToHead3(ListNode listNode) {
            //创建一个栈
            Stack<Integer> stack = new Stack<>();
            //依次将链表的值压栈
            while (listNode != null) {
                stack.add(listNode.val);
                listNode = listNode.next;
            }
            ArrayList<Integer> ret = new ArrayList<>();
            //依次弹栈
            while (!stack.isEmpty()) {
                ret.add(stack.pop());
            }
            return ret;
        }

 

 

牛客在线编程题

cyc2018解题思路

posted @ 2019-09-09 19:49  cqutwangyu  阅读(145)  评论(0编辑  收藏  举报