问题
输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。
示例 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; }
* }
*/
问题分析
两种解法:
1、利用“栈”来进行辅助存储
因为栈具有 先进后出 的特点,正好可以通过栈:
从前往后遍历链表,并将遍历到的节点(!=null),压入栈stack中。在遍历链表结束以后,再将栈中的元素一个个出栈,arr[i++] = stack.pop().val; 实现逆序的将链表中各个节点的值,存入到数组中
2、递归解决
1)实际上,该方法使用递归解决的话,就必须先要明确:因为递归方法是在便利的过程中进行操作的,所以一开始不能定义为数组来存储 链表逆序的val顺序(因为链表的长度是未知的)。所以,可以采取 集合 来先存储(因为集合 可以扩容)。
2)确定递归的终止条件:
head == null
对应:遍历到链表的末尾。实际上,这个条件也包含了 链表本身为空,即,最初的 head == null 的情况。
3)递归过程中进行的操作:
function(head.next,list);//递归调用下一个节点
list.add(head.val);//在递归返回的过程中,将链表中的每个节点对应的val值,放到list中去
代码实现
1、利用“栈”来进行辅助存储
class Solution {
public int[] reversePrint(ListNode head) {
//因为题目中没有说明是否可以改变原链表的顺序,所以借助栈来实现
ListNode cur = head;//定义一个用于遍历链表的指针cur,并指向链表的“头节点”
int count = 0;//用于记录链表长度的变量
//定义一个栈用于存储链表中的节点
Stack<ListNode> stack = new Stack();
//链表中,用于遍历的指针cur指向的节点不为空的时候,循环就需要进行
while(cur != null){
stack.push(cur);
count ++ ;
cur = cur.next;//这个是实现遍历链表的语句
}
int[] arr = new int[count];
//当栈非空时,要将栈中的元素出栈,并且将刚出栈的元素的val值,赋值给arr[]中的相应元素
// ListNode temp ;//暂存出栈的节点
int i=0;//控制数组下标的变量
while(!stack.empty()){
arr[i++] = stack.pop().val;
// temp = stack.pop();
// arr[i++] = temp.val;
}
return arr;
}
}
2、使用递归
class Solution {
public int[] reversePrint(ListNode head) {
//使用一个ArrayList来逆序存储各个节点val(利用ArrayList的长度可变的原理,因为在刚开始的时候,是不知道转化后的数组的长度的)。并在最终,通过list.get(index),来读取集合中的元素,赋值给数组,并返回,即可
//因为是引用类型,所以,实际上是:由递归调用而创建的所有的栈空间,使用同一个list
ArrayList<Integer> list = new ArrayList<Integer>();//类型推断
//尝试一下,使用递归的解法
function(head, list);
//将list转化为对应的数组,并返回
int[] arr = new int[list.size()];
for(int i=0;i<arr.length;i++){
arr[i] = list.get(i);//利用的是集合的“查”的方法
}
return arr;
}
//注意:这里使用递归来解题的划分依据:
//递归的终止条件是遍历到的节点本身为空(head == null),此时,因为该节点本身不存在,所以不需要做list.add()操作
//----不能将head.next == null,作为递归的终止条件。这是因为:此时的话,递归终止条件就没有办法包含:head节点本身为空(链表为空的情况)
//但是,在非递归终点的条件下,需要做list.add()的操作
public void function(ListNode head,List list){
//是递归的终点,也包含了第一个节点就是递归终点的情况
if(head == null){
//到达最后一个节点
return;
}
function(head.next,list);
//在递归返回的过程中,将链表中的每个节点对应的val值,放到list中去
list.add(head.val);
return;
}
}
加油,坚持每天刷题。
并且,在刷题的过程中,坚持练习 递归 的思想!!!