输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。
方法一:显式使用栈
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
vector<int> reversePrint(ListNode* head) {
stack<int> s;
vector<int> ans;
ListNode* pNode = head;
while (pNode)
{
s.push(pNode->val);
pNode = pNode->next;
}
while (!s.empty())
{
ans.push_back(s.top());
s.pop();
}
return ans;
}
};
注意点:
- 遍历链表的代码要熟悉。
- stack的使用,push()、top() 和 pop()。其中pop()只弹出栈顶元素,并不返回栈顶元素。
# python
from typing import List
class ListNode:
def __init__(self, x) -> None:
self.val = x
self.next = None
class Solution:
def reversePrint(self, head: ListNode) -> List[int]:
stack = []
res = []
node = head
while node:
stack.append(node.val)
node = node.next
while stack:
res.append(stack.pop())
return res
注意点:
- 在python中,array和stack都是用list实现的。向数组中添加元素和向堆栈中压入元素都用append(),从堆栈中弹出元素用pop(),返回值为栈顶元素。如果只想查看栈顶元素,可以用stack[-1]。
- python中想要判断列表为空不需要调用函数。False,0,None,{},[],()都表示假,因此直接while list:即可。
// java
package myjava;
import java.util.Stack;
// singly-linked list
class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
next = null;
}
}
public class Solution {
public int[] reversePrint(ListNode head) {
ListNode node = head;
Stack<Integer> st = new Stack<Integer>();
while (node != null) {
st.push(node.val);
node = node.next;
}
int i = 0;
int[] res = new int[st.size()];
while (i < res.length) {
res[i++] = st.pop();
}
return res;
}
// 以下为测试
public static void main(String[] args) {
ListNode head = new ListNode(1);
head.next = new ListNode(3);
head.next.next = new ListNode(2);
Solution sol = new Solution();
int[] res = sol.reversePrint(head);
for (int x : res) {
System.out.println(x);
}
}
}
注意点:
- 将Stack中的元素pop出来存入数组int[]的时候,注意代码中:
int i = 0; int[] res = new int[st.size()]; while (i < res.length) { res[i++] = st.pop(); }
i < res.length不能写成i < st.size(),因为随着st的pop,堆栈的size在减小,而res.length不变。
方法二:用递归隐式使用栈
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
vector<int> reversePrint(ListNode* head) {
if (head == NULL)
{
return{};
}
vector<int> ans = reversePrint(head->next);
ans.push_back(head->val);
return ans;
}
};
注意点:
- 减治思想,长度为n的链表,先打印后n - 1个结点,然后打印第一个结点。
// java
import java.util.ArrayList;
// singly-linked list
class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
}
}
public class Solution {
ArrayList<Integer> tmp = new ArrayList<Integer>();
public int[] reversePrint(ListNode head) {
recur(head);
int[] res = new int[tmp.size()];
for (int i = 0; i < tmp.size(); i++) {
res[i] = tmp.get(i);
}
return res;
}
void recur(ListNode head) {
if (head == null) {
return;
}
recur(head.next);
tmp.add(head.val);
}
}
注意点:
- 通过递归方法recur将链表值从尾到头存入动态数组ArrayList。
- 将ArrayList转化成int[],并没有什么好方法,只能逐个复制。ArrayList提供的get(i)方法可以提取第i个元素。ArrayList的toArray方法只能将ArrayList转换为Integer[]这种引用类型,而不能转换为int[]这种基本类型。
- 用java写起来及其麻烦,是因为题目给的返回值类型为int[]静态数组,没办法往尾巴后面加,所以要先用动态数组递归,再转换成静态数组。
# python
from typing import List
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
class Solution:
def reversePrint(self, head: ListNode) -> List[int]:
return self.reversePrint(head.next) + [head.val] if head else []
注意点:
- python写法之所以简单,是因为:1. 不需要声明变量类型。2. python中list的操作比c++和java中动态数组的操作更简单。3. xxx if 条件 else xxx语句的使用。