三种解法剑指 Offer 06. 从尾到头打印链表附完整可运行代码
Posted 来老铁干了这碗代码
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了三种解法剑指 Offer 06. 从尾到头打印链表附完整可运行代码相关的知识,希望对你有一定的参考价值。
立志用最少的代码做最高效的表达
输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。
示例 1:
输入:head = [1,3,2]
输出:[2,3,1]
限制:
0 <= 链表长度 <= 10000
解法1:栈
利用栈先进后出的原理,将链表遍历并存入栈,新建数组,将栈依次弹出,
得到的就是倒序的数组。
本来遍历一遍就出结果的题,我也不知为啥脑子抽了要用栈。。
class Solution6 {
public int[] reversePrint(ListNode head) {
// 避免出现空指针
if(head == null) return new int[0];
List<Integer> array = new ArrayList<Integer>();
int num = 0;
Stack<Integer> st = new Stack<Integer>();
while(true) {
st.push(head.val);
head = head.next;
if(head == null) {
break;
}
}
while(!st.empty()) {
num++;
array.add(st.peek());
st.pop();
}
return array.stream().mapToInt(Integer::valueOf).toArray();
}
}
解法2
直接使用ArrayList动态数组,将栈值依次放入数组,然后遍历数组,将数组置换,或使用reverse()。最后转化为int[]即可。
class Solution7 {
public int[] reversePrint(ListNode head) {
// 避免出现空指针
if(head == null) return new int[0];
List<Integer> list = new ArrayList<Integer>();
while(true) {
list.add(head.val);
head = head.next;
if(head == null) break;
}
int len = list.size()-1;
int num = 0;
while(num < len) {
int t = list.get(num);
list.set(num, list.get(len));
list.set(len, t);
num++; len--;
}
return list.stream().mapToInt(Integer::valueOf).toArray();
}
}
解法3
先进行一遍遍历,将链表长度求出,然后定义对应长度的int数组,最后倒序赋值,返回即可。
class Solution8 {
public int[] reversePrint(ListNode head) {
// 避免出现空指针
if(head == null) return new int[0];
int count = 0;
ListNode tmp_head = head;
while(tmp_head != null) {
count++;
tmp_head = tmp_head.next;
}
int array[] = new int[count];
for(int i = count-1; i >= 0; i--) {
array[i] = head.val;
head = head.next;
}
return array;
}
}
完整可运行代码
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import java.util.Vector;
public class 剑指_Offer_06_从尾到头打印链表 {
public static void main(String[] args) {
// 声明链表,这里的Solution6、7、8分别代表三种解法。
Solution8 solution = new Solution8();
ListNode head = new ListNode(1);
ListNode n1 = new ListNode(2);
ListNode n3 = new ListNode(3);
ListNode n4 = new ListNode(4);
ListNode n5 = new ListNode(5);
n4.next = n5;
n3.next = n4;
n1.next = n3;
head.next = n1;
// 输出数组
int node[] = solution.reversePrint(head);
for(int i = 0; i < node.length; i++) {
System.out.println(node[i] + " ");
}
}
}
class ListNode {
int val;
ListNode next;
ListNode(int x) { val = x; }
}
// 解法1:栈
// 利用栈先进后出的原理,将链表遍历并存入栈,新建数组,将栈依次弹出,
// 得到的就是倒序的数组。
// 本来遍历一遍就出结果的题,我也不知为啥脑子抽了要用栈。。
class Solution6 {
public int[] reversePrint(ListNode head) {
// 避免出现空指针
if(head == null) return new int[0];
List<Integer> array = new ArrayList<Integer>();
int num = 0;
Stack<Integer> st = new Stack<Integer>();
while(true) {
st.push(head.val);
head = head.next;
if(head == null) {
break;
}
}
while(!st.empty()) {
num++;
array.add(st.peek());
st.pop();
}
return array.stream().mapToInt(Integer::valueOf).toArray();
}
}
// 解法2,直接使用ArrayList动态数组,最后转化为int即可。
class Solution7 {
public int[] reversePrint(ListNode head) {
// 避免出现空指针
if(head == null) return new int[0];
List<Integer> list = new ArrayList<Integer>();
while(true) {
list.add(head.val);
head = head.next;
if(head == null) break;
}
int len = list.size()-1;
int num = 0;
while(num < len) {
int t = list.get(num);
list.set(num, list.get(len));
list.set(len, t);
num++; len--;
}
return list.stream().mapToInt(Integer::valueOf).toArray();
}
}
// 解法3,先进行一遍遍历,将链表长度求出,然后定义对应长度的int数组,最后倒序赋值,返回即可。
class Solution8 {
public int[] reversePrint(ListNode head) {
// 避免出现空指针
if(head == null) return new int[0];
int count = 0;
ListNode tmp_head = head;
while(tmp_head != null) {
count++;
tmp_head = tmp_head.next;
}
int array[] = new int[count];
for(int i = count-1; i >= 0; i--) {
array[i] = head.val;
head = head.next;
}
return array;
}
}
测试用例
- 功能测试:输入的链表有多个节点;输入的链表只有一个节点
- 特殊输入测试:输入的链表头结点指针为null
本题考点
- 考查应聘者对单向链表的理解和编程能力
- 考查应聘者对循环、递归和栈3个相互关联的概念的理解。
以上是关于三种解法剑指 Offer 06. 从尾到头打印链表附完整可运行代码的主要内容,如果未能解决你的问题,请参考以下文章