题解 | #从尾到头打印链表#
从尾到头打印链表
http://www.nowcoder.com/practice/d0267f7f55b3412ba93bd35cfa8e8035
题解一:递归
题解思路:使用递归先走到链表的末尾,再在回溯时将链表节点中的值加入到数组中。
递归边界: head == NULL;
递归阶段:一直传入head->next;
回溯阶段:将值加入到数组;
图示:
复杂度分析:
时间复杂度:,回溯遍历了整个链表
空间复杂度:,去掉输出最终结果vector的数组,栈递归深度为N,所以使用栈的空间为O(N)
实现如下:
class Solution {
public:
vector<int> ans;
void recur(ListNode* head){
if(head == NULL) //head == NULL表示递归结束
return;
recur(head->next);
ans.push_back(head->val); // 回溯将链表值加入到ans
}
vector<int> printListFromTailToHead(ListNode* head) {
recur(head);
return ans;
}
};题解二:使用std::reverse()
解题思路: 使用vector保存链表中的,然后使用reverse()反转整个vector
复杂度分析:
时间复杂度: ,使用while循环遍历了整个链表O(n),翻转数组时间复杂度O(n);
空间复杂度: ,去掉输出最终结果vector的数组,没有再申请其他空间了
实现如下:
class Solution {
public:
vector<int> printListFromTailToHead(ListNode* head) {
vector<int> ans;
while(head)
{
ans.push_back(head->val);
head = head->next;
}
reverse(ans.begin(),ans.end()); //反转整个vector
return ans;
}
};题解三: 反转链表 (先将反转链表,再依次遍历打印值)
主要思路:
1.定义两个指针pre,cur; pre在前,cur在后; cur初始为NULL, pre初始为链表头。
2.每次让pre的next指向cur,实现一次局部反转; 之后,pre与cur同时向前移动一位。
3. 当pre为NULL表示反转完成。
4.从cur开始遍历反转之后的链表
图示:
复杂度分析:
时间复杂度:O(N),使用while循环反转整个链表O(n),遍历得到结果O(n);
空间复杂度:O(N),去掉输出最终结果vector的数组,没有再申请其他空间了
实现如下
class Solution {
public:
vector<int> printListFromTailToHead(ListNode* head) {
ListNode* cur = NULL,*pre = head;
while(pre)
{
ListNode* p = pre->next; // pre之后值
pre->next = cur; // 局部反转一次
cur = pre; //cur 向后移动一位
pre = p; //pre 向后移动一位
}
vector<int> ans;
while(cur) //反转之后cur,指向反转后链表的头
{
ans.push_back(cur->val);
cur = cur->next;
}
return ans;
}
};本专栏记录在牛客网上AC的每一题,写下题解。 未来2年完成2000编程题的题解。 2021.12.29更新,最进准备毕设,断更了,会尽快做完毕设,继续做这一件事情
海康威视公司福利 1182人发布