06. 从尾到头打印链表

链接

https://leetcode-cn.com/problems/cong-wei-dao-tou-da-yin-lian-biao-lcof/
难度: #简单

题目

输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。

示例 1:

输入:head = [1,3,2]
输出:[2,3,1]

限制:
0 <= 链表长度 <= 10000

代码框架

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
 public int[] reversePrint(ListNode head) {

 }
}

题目解析

辅助思考图形:
[[06. 从尾到头打印链表.drawio]]

解答思路1:
递归遍历链表,
使用List保存链表的值,
深度优先遍历,
从链表的最后一个元素开始保存,
这样List保存的元素就是反转过的,
然后将List转换成数组返回即可。

解答思路2:
递归遍历链表,
使用全局变量保存计算过程的数据,
深度优先遍历,
到最后一个元素时,
能知道数组的大小,
然后从最后一个元素开始保存数据,
从数组的第一个元素开始保存,
直到回到链表的第一个元素反转完成。

解答思路3:
使用While循环正向遍历链表,
并将元素按照顺序保存在List中,
然后对List进行反转即可。

解答思路4:
使用While循环正向遍历链表,
计算出元素的总数,
然后申请对应大小的数组,
重新While循环正向遍历链表,
将遍历到的元素从数组的尾部开始插入,
实现链表的反转。

测试用例

package edu.yuwen.sowrd.num06.solution;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import edu.yuwen.sowrd.num06.ListNode;
import edu.yuwen.sowrd.num06.sol4.Solution;

public class SolutionTest {
    /**
     * 输入:head = [1,3,2]
     * 输出:[2,3,1]
     */
    @Test
    public void testCase1() {
        Solution solution = new Solution();

        ListNode node1 = new ListNode(1);
        ListNode node2 = new ListNode(3);
        ListNode node3 = new ListNode(2);

        node1.next = node2;
        node2.next = node3;

        ListNode head = node1;
        int[] res = solution.reversePrint(head);
        Assertions.assertEquals(3, res.length);
        Assertions.assertEquals(2, res[0]);
        Assertions.assertEquals(3, res[1]);
        Assertions.assertEquals(1, res[2]);
    }
}

解答1

package edu.yuwen.sowrd.num06.sol1;

import java.util.ArrayList;
import java.util.List;

import edu.yuwen.sowrd.num06.ListNode;

public class Solution {

    public int[] reversePrint(ListNode head) {
        List resList = new ArrayList<>();

        recurve(head, resList);
        int[] resArray = new int[resList.size()];
        for (int i = 0; i < resList.size(); i++) {
            resArray[i] = resList.get(i);
        }

        return resArray;
    }

    private void recurve(ListNode head, List res) {
        if (head == null) {
            return;
        }

        recurve(head.next, res);
        res.add(head.val);
    }
}

解答2

package edu.yuwen.sowrd.num06.sol2;

import edu.yuwen.sowrd.num06.ListNode;

/**
 * 解答思路2:
 * 递归遍历链表,
 * 使用全局变量保存计算过程的数据,
 * 深度优先遍历,
 * 到最后一个元素时,
 * 能知道数组的大小,
 * 然后从最后一个元素开始保存数据,
 * 从数组的第一个元素开始保存,
 * 直到回到链表的第一个元素反转完成。
 *
 */
public class Solution {
    // 保存返回结果的数组
    int[] resArray;
    // 数组的大小
    int count;
    // 数组当前的位置索引
    int index;

    public int[] reversePrint(ListNode head) {
        if (head == null) {
            return new int[0];
        }
        resArray = null;
        count = 0;
        index = 0;
        recurve(head);
        return resArray;
    }

    private void recurve(ListNode head) {
        if (head.next == null) {
            resArray = new int[count + 1];
            // 找到最后一个结点,放到结果数组的第一个
            resArray[0] = head.val;
            return;
        }
        // 数组大小加1
        count++;
        // 遍历下一个元素
        recurve(head.next);
        // 索引向后移动一位,用于保存当前的元素
        index++;
        resArray[index] = head.val;
    }
}

解答3

package edu.yuwen.sowrd.num06.sol3;

import java.util.ArrayList;
import java.util.List;

import edu.yuwen.sowrd.num06.ListNode;

/**
 * 解答思路3:
 * 使用While循环正向遍历链表,
 * 并将元素按照顺序保存在List中,
 * 然后对List进行反转即可。
 */
public class Solution {

    public int[] reversePrint(ListNode head) {
        if (head == null) {
            return new int[0];
        }

        List list = new ArrayList<>();
        ListNode current = head;
        while (current != null) {
            // 先按照顺序保存
            list.add(current.val);
            // 移动到下一个结点
            current = current.next;
        }

        // 反转List保存到返回数组中
        int size = list.size();
        int[] resArray = new int[size];
        for (int i = 0; i < size; i++) {
            // 从list中的最后一个开始保存,到结果数组的第一个
            resArray[i] = list.get(size - 1 - i);
        }

        return resArray;
    }
}

解答4 推荐

package edu.yuwen.sowrd.num06.sol4;

import edu.yuwen.sowrd.num06.ListNode;

/**
 * 解答思路4:
 * 使用While循环正向遍历链表,
 * 计算出元素的总数,
 * 然后申请对应大小的数组,
 * 重新While循环正向遍历链表,
 * 将遍历到的元素从数组的尾部开始插入,
 * 实现链表的反转。
 */
public class Solution {

    public int[] reversePrint(ListNode head) {
        if (head == null) {
            return new int[0];
        }

        // 计算链表的大小
        int size = 0;
        ListNode current = head;
        while (current != null) {
            size++;
            // 移动到下一个结点
            current = current.next;
        }

        int[] resArray = new int[size];
        current = head;
        for (int i = size - 1; i >= 0; i--) {
            // 将遍历到的元素从数组的尾部开始插入
            resArray[i] = current.val;
            // 移动到下一个结点
            current = current.next;
        }

        return resArray;
    }
}

你可能感兴趣的:(06. 从尾到头打印链表)