从尾到头打印链表
题目:输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。
示例 1:
输入:head = [1,3,2]
输出:[2,3,1]
限制:
0 <= 链表长度 <= 10000
解题思路
看到题目后首先想到的就是C++中stl提供的反转(reverse)算法,先遍历整个链表,将每个结点的数据都尾插到vector容器中,当遍历完之后将整个容器反转,这样就能解出此题了。
1.反转代码
代码如下:
class Solution {
public:
vector<int> reversePrint(ListNode* head) {
vector<int> v;
ListNode *p=head;
while(p)
{
v.push_back(p->val);
p=p->next;
}
reverse(v.begin(),v.end());
return v;
}
};
执行用时:0 ms, 在所有 C++ 提交中击败了100.00%的用户
内存消耗:8.6 MB, 在所有 C++ 提交中击败了87.77%的用户
2.借助deque容器实现
当用完自带的反转算法解完题后,我又尝试着运用vector+deque两个容器来实现算法。因为vector容器的弊端就是头插比较麻烦,而deque容器则能完美的解决头插的问题。首先将链表遍历并将每个结点的数据都头插到deque容器中,最后遍历完成后将deque容器里的数据都复制给vector容器,最后返回vector。
代码如下:
class Solution {
public:
vector<int> reversePrint(ListNode* head) {
deque<int> d;
vector<int> v;
ListNode *p=head;
while(p)
{
d.push_front(p->val);
p=p->next;
}
v.assign(d.begin(),d.end());
return v;
}
};
执行用时:8 ms, 在所有 C++ 提交中击败了71.27%的用户
内存消耗:9 MB, 在所有 C++ 提交中击败了34.92%的用户
结论:可以看到这种解法没有第一种那么理想。这说明人家标准库里提供的算法都是大佬们精心优化过的,就是牛逼…(能用标准库里的算法就尽量使用)
拓展
看了官方给的答案发现还有很多好的解法,这里我也拿过来给大家参考。
递归实现
代码如下:
class Solution {
public:
vector<int> res;
vector<int> reversePrint(ListNode* head) {
if (!head) return res;
reversePrint(head->next);
res.push_back(head->val);
return res;
}
};
作者:z1m
链接:https://leetcode-cn.com/problems/cong-wei-dao-tou-da-yin-lian-biao-lcof/solution/python3-c-by-z1m/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
复杂度分析
时间复杂度:O(n)O(n),递归 nn 次,时间间复杂度为 O(n)O(n),递归函数中的操作时间复杂度为 O(1)O(1),总时间复杂度为 O(n)\times O(1)=O(n)O(n)×O(1)=O(n)。
空间复杂度:O(n)O(n),递归将占用链表长度的栈空间。
堆栈实现
代码如下:
class Solution {
public:
vector<int> res;
vector<int> reversePrint(ListNode* head) {
stack<int> st;
while(head){// push
st.push(head->val);
head = head->next;
}
while(!st.empty()){ // pop
res.push_back(st.top());
st.pop();
}
return res;
}
};
作者:z1m
链接:https://leetcode-cn.com/problems/cong-wei-dao-tou-da-yin-lian-biao-lcof/solution/python3-c-by-z1m/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
复杂度分析
时间复杂度:O(n)O(n),pushpush 的间复杂度为 O(n)O(n),poppop 的间复杂度为 O(n)O(n)。
空间复杂度:O(n)O(n),使用了额外的 res 和 堆栈。