《剑指offer》-从尾到头打印链表

从尾到头打印链表

题目:输入一个链表的头节点,从尾到头反过来打印每个节点的值。

其实有一种偷鸡的方法,因为这道题返回的是一个数组,那么我先把链表的值正序存到数组里,然后将数组翻转返回即可

第一种方法:翻转链表

我的方法:
首先判断这个是不是空对象,是空对象的话,直接返回空数组
再判断 listNode.next 是不是空,是空的说,说明这个链表只有1个值,则add之后直接返回
接着创建了3个对象,分别为 first、second、third。first指向前一个对象,second指向当前对象,third指向后一个对象。
判断second.next是否为空,如果不为空,说明second不是最后一个值。然后先将second.next保存到third中,然后将second.next指向first。 之后让 first 和 second整体向后移一个位置,继续判断。如果second为空,则说明second为最后一个对象,这时候让 second.next指向first,即翻转成功

/**
 1.    public class ListNode {
 2.        int val;
 3.        ListNode next = null;
 4.        ListNode(int val) {
 5.            this.val = val;
 6.        }
 7.    }
 8. */
import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        ArrayList<Integer> ans = new ArrayList<Integer>(100);
        if(listNode == null){
            return ans;
        }
        if(listNode.next == null){
            ans.add(new Integer(listNode.val));
            return ans;
        }
        ListNode first = listNode;
        ListNode second = first.next;
        first.next = null;
        ListNode third = null;
        while(second.next != null){
            third = second.next;
            second.next = first;
            first = second;
            second = third;
        }
        second.next = first;
        while(second != null){
            ans.add(new Integer(second.val));
            second = second.next;
        }
        return ans;
        
    }
}

测试用例:

  1. 功能测试
    1. 输入的链表有多个节点
    2. 输入的链表只有1个节点
  2. 特殊输入测试
    1. 输入的链表头结点指针为null

简洁版:
其实对于当前指针,只有两种情况,空或不空。这里将其next指向交给下一个循环判断
不空的话,就 next = listNode.next, 这个next 是否为空,交给下一个循环进行判断,这里是将当前对象的next保存下来,然后再让 listNode.next = pre 指向前一个对象。然后让 pre 和 listNode整体向后移动一个位置,再进行判断
空的话,就结束这个修改 next 的循环

ArrayList<Integer> list=new ArrayList<Integer>();
ListNode pre=null;
ListNode next=null;
while(listNode!=null){
    next=listNode.next;
    listNode.next=pre;
    pre=listNode;
    listNode=next;
}
while(pre!=null){
    list.add(pre.val);
    pre=pre.next;
}
return list;
第二种:先进后出,那么就用栈来实现

这里使用了,stack这个包

import java.util.ArrayList;
import java.util.Stack;
public class Solution {
    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        Stack<Integer> myStack = new Stack<Integer>();
        ArrayList<Integer> ans = new ArrayList<Integer>(100);
        while(listNode != null){
            myStack.push(listNode.val);
            listNode = listNode.next;
        }
        while(!myStack.empty()){
            ans.add(myStack.pop());
        }
        return ans;
    }
}
第三种:使用递归

判断当前节点是否是空,不是空的话,就将其值加入ans里,然后判断下一个节点是否为空,不为空的话,递归。
这里需要注意的是,ans.add的位置。它的位置是在下一个节点递归结束之后,才add当前节点的val。如果将其放到第二个判断之上,那么返回的结果只有整个链表的最后一个值。

import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        ArrayList<Integer> ans = new ArrayList<Integer>(100);
        if(listNode != null){
            if(listNode.next != null){
                ans = printListFromTailToHead(listNode.next);
            }
            ans.add(listNode.val);
        }
        return ans;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值