剑指offer面试题6(java版):从尾到头打印链表

面试题6:从尾到头打印链表

题目描述

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

思路

  • 先进后出:栈结构, LinkedList可以实现栈数据结构
  • 稍微注意一下泛型问题

复杂度

时间复杂度:O(n)
空间复杂度:O(n)

第三次做; 递归版, 空间幅度高一些, 毕竟使用了系统栈; 要理清楚递归逻辑, 递归逻辑要能够体现:1)新条件新递归 2)当前条件
import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        //递归版
        ArrayList<Integer> al = new ArrayList<>();
        core(al, listNode);
        return al;
    }
    //递归函数逻辑: 把head之后的节点的val都加入al后(新条件新递归), 再把head的val加入al(当前条件)
    private void core(ArrayList<Integer> al, ListNode head){
        //base case
        if(head==null)
            return;
        //新条件新递归
        core(al, head.next);
        //当前条件
        al.add(head.val);
    }
}
第三次做; 反转链表法的时间复杂度是O(N), 空间复杂度是O(1)
import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        ArrayList<Integer> al = new ArrayList<>();
        if(listNode==null)
            return al;
        ListNode left=null, cur=listNode, right;
        while(cur!=null){
            //save
            right = cur.next;
            //change
            cur.next = left;
            //update
            left = cur;
            cur = right;
        }
        //还原
        cur = left;
        right = null;
        while(cur!=null){
            //save
            left = cur.next;
            //update al
            al.add(cur.val);
            //change
            cur.next = right;
            //update
            right = cur;
            cur = left;
        }
        return al;
    }
}
第二次做, 递归版, 此递归含义的理解:先把i+1,…,last的val加入res,再把i的val加入res;递归函数的处理逻辑并没有使用到return的结果, 这个return是返回给外部的
import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> res = new ArrayList<>();
    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        //base case
        if(listNode == null)
            return res;
        //先把i+1,...last的val加入res
        printListFromTailToHead(listNode.next);
        //再把i的val加入res
        res.add(listNode.val);
        return res; //递归函数的处理逻辑并没有使用到return的结果, 这个return是返回给外部的
    }
}
第二次做, 空间复杂度为O(1)的解法, 反转链表法
import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        //空间复杂度O(1)的解法
        ArrayList<Integer> res = new ArrayList<>();
        if(listNode==null)
            return res;
        ListNode left=null, curr=listNode, right=null;
        //reverse linkedlist
        while(curr!=null){
            //save next node
            right = curr.next;
            //chage direction
            curr.next = left;
            //update pointer\
            left = curr;
            curr = right;
        }
        curr = left;
        while(left!=null){
            res.add(left.val);
            left = left.next;
        }
        //restore linkedlist
        while(curr!=null){
            left = curr.next;
            //
            curr.next = right;
            //
            right = curr;
            curr = left;
        }
        return res;
    }
}
import java.util.ArrayList;
import java.util.LinkedList;
public class Solution {
    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        // 健壮性判断. 加上下面这个健壮性判断就错了!
        //if(listNode == null)
            //return null;
        // 开始处理
        LinkedList<Integer> ll = new LinkedList();
        while(listNode != null){
            ll.addFirst(listNode.val);
            listNode = listNode.next;
        }
        ArrayList<Integer> al = new ArrayList();
        while(!ll.isEmpty()){
            al.add(ll.remove());
        }
        return al;
    }
}
使用栈
import java.util.ArrayList;
import java.util.Stack;
public class Solution {
    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        ArrayList<Integer> al = new ArrayList<>();
        if(listNode==null) return al;
        Stack<Integer> s = new Stack<>();
        while(listNode!=null){
            s.push(listNode.val); //直接压入数值,而不是节点,会省点空间
            listNode = listNode.next;
        }
        while(!s.isEmpty())
            al.add(s.pop());
        return al;
    }
}
递归版
import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        //input check
        ArrayList<Integer> al = new ArrayList<>();
        if(listNode==null) return al;
        Core(listNode, al);
        return al;
    }
    public void Core(ListNode listNode, ArrayList<Integer> al){
        if(listNode==null) return;
        Core(listNode.next,al);
        al.add(listNode.val);
    }
}
递归版(简洁)
import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> al = new ArrayList<>();
    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        if(listNode == null) return al;
        printListFromTailToHead(listNode.next);
        al.add(listNode.val);
        return al;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值