核心考点:链表相关,多结构混合使用,递归
输入一个链表的头结点,按链表从尾到头的顺序返回每个结点的值(用数组返回)。
解析一:(不提倡)
我们可以通过所给头结点依次遍历链表当中的结点,并将遍历到的结点值存放到数组当中,此时数组当中存放的便是按链表从头到尾的每个结点的值,然后我们将数组进行逆置便可以得到按链表从尾到头的每个结点的值。
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* ListNode(int x) :
* val(x), next(NULL) {
* }
* };
*/
class Solution {
public:
vector<int> printListFromTailToHead(ListNode* head) {
vector<int> v;
//将链表当中的数据从头到尾放到容器v当中
while (head != NULL)
{
v.push_back(head->val);
head = head->next;
}
//将容器v进行逆置
reverse(v.begin(), v.end());
return v; //返回容器v
}
};
解析二:(较提倡)
我们只能从链表头结点遍历到尾结点,但题目却要我们按链表从尾到头的顺序返回每个结点的值,也就是说我们先遍历到的结点值要后输出,此时你想到了什么?当然是栈啦,栈就是一个先进后出的容器。
我们依次将遍历到的结点值入栈,遍历结束后再将栈当中的数据依次弹出放到数组当中即可。
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* ListNode(int x) :
* val(x), next(NULL) {
* }
* };
*/
class Solution {
public:
vector<int> printListFromTailToHead(ListNode* head) {
stack<int> st;
//依次将遍历到的结点值入栈
while (head != NULL)
{
st.push(head->val);
head = head->next;
}
vector<int> v;
//将栈中的数据依次出栈,存储到容器v当中
while (!st.empty())
{
v.push_back(st.top());
st.pop();
}
return v; //返回容器v
}
};
解析三:(正解)
对于该题目,我们还可以采用递归的方式来解决。递归函数当中的流程设置为先递归、再打印,这样就可以优先进行递归,直到递归返回时再依次进行结点值的打印。
当然,每个递归函数都有一个递归结束的条件,这里递归结束的条件就是碰到空指针,此时说明链表递归遍历结束。递归结束后递归函数会一个个返回,在返回过程中会一个个打印结点值,递归返回的方向就是从链表尾到链表头,所以此时打印结点值的顺序也就是从尾到头了。
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* ListNode(int x) :
* val(x), next(NULL) {
* }
* };
*/
class Solution {
public:
vector<int> printListFromTailToHead(ListNode* head) {
vector<int> v;
dfs(v, head); //递归进行输出
return v;
}
//递归函数
void dfs(vector<int>& v, ListNode*& pNode)
{
if (pNode == NULL) //传入结点地址为空,递归结束的标志
return;
dfs(v, pNode->next); //先递归
v.push_back(pNode->val); //递归结束后(碰到NULL返回)再进行结点值输出
}
};