三种解法剑指 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. 从尾到头打印链表附完整可运行代码的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode | 面试题06. 从尾到头打印链表剑指OfferPython

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

《剑指offer》第五题(重要!从尾到头打印链表)

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

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

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