06. 从尾到头打印链表
一、题目描述
输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。
示例 1:
输入:head = [1,3,2]
输出:[2,3,1]
限制:
0 <= 链表长度 <= 10000
二、解题思路
方法一:用栈实现
链表只能 从前至后 访问每个节点,而题目要求 倒序输出 各节点值,这种 先入后出 的需求可以借助 栈 来实现。
算法流程:
1.入栈: 遍历链表,将各节点值 push 入栈。
2.出栈: 将各节点值 pop 出栈,存储于数组并返回。
复杂度分析:
时间复杂度 O(N): 入栈和出栈共使用 O(N) 时间。
空间复杂度 O(N): 辅助栈 stack 和数组 res 共使用 O(N) 的额外空间。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
class Solution { public: vector<int> printListFromTailToHead(ListNode* head) { vector<int> v; stack<int> s; while(head!=NULL) { s.push(head->val); head=head->next; } while(!s.empty()) { v.push_back(s.top()); s.pop(); } return v; } };
|
方法二:使用C++自带的翻转函数reverse实现反转
(头文件为algorithm)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
class Solution { public: vector<int> printListFromTailToHead(ListNode* head) { vector<int> v; while(head!=NULL) { v.push_back(head->val); head=head->next; } reverse(v.begin(),v.end()); return v; } };
|
方法三:递归法
利用递归,先递推至链表末端;回溯时,依次将节点值加入列表,即可实现链表值的倒序输出。
递归解析:
终止条件: 当 head == None 时,代表越过了链表尾节点,则返回空列表;
递推工作: 访问下一节点 head.next ;
回溯阶段:
C++: 将当前节点值 head.val 加入列表 tmp ;
复杂度分析:
时间复杂度 O(N): 遍历链表,递归N 次。
空间复杂度 O(N): 系统递归需要使用 O(N) 的栈空间。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
class Solution { public: vector<int> v; vector<int> printListFromTailToHead(ListNode* head) { if(head!=NULL) { printListFromTailToHead(head->next); v.push_back(head->val); } return v; } };
|
方法四:迭代法
①、先定义三个节点p、q、m;p头结点之后的第1个节点;q头结点之后的第2节点;m头结点之后的第3个节点。然后将头结点的next指向为null
②、判断m是否为空,实现逆序每个节点,达到直接next指向掉头;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| void List::reverse1() { LINKNODE* p = head->next; LINKNODE* q = head->next->next; LINKNODE* m = head->next->next->next; p->next = NULL;
while (m) { q->next = p; p = q; q = m; m = m->next; } q->next = p; head->next = q; }
|
三、具体程序实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
| #include <iostream> #include <stack> using namespace std;
class List { public: List() { create_List(); }; ~List() { clear(); };
void create_List();
void insert(const int& d);
void reverse1();
void reverse2();
void print();
private:
struct LINKNODE { int data; LINKNODE* next; LINKNODE(const int& d) : data(d), next(nullptr) {} };
LINKNODE* head;
void clear() { LINKNODE* p = head;
while (p) { LINKNODE* q = p->next; delete p; p = q; } }
};
void List::create_List() { head = new LINKNODE(0); }
void List::insert(const int& d) { LINKNODE* p = new LINKNODE(d); p->next = head->next; head->next = p; }
void List::reverse1() { LINKNODE* p = head->next; LINKNODE* q = head->next->next; LINKNODE* m = head->next->next->next; p->next = NULL;
while (m) { q->next = p; p = q; q = m; m = m->next; } q->next = p; head->next = q; }
void List::print() { for (LINKNODE* p = head->next; p; p = p->next) { cout << p->data << endl; } }
int main() { List list; list.insert(2); list.insert(3); list.insert(1); cout << "新建链表:" << endl; list.print();
cout << "反转链表1:" << endl; list.reverse1(); list.print(); return 0; }
|
以递归法为例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
| #include<iostream> #include<vector> #include<stack> #include<algorithm> using namespace std; struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL){ } };
class Solution1 { public: vector<int> v; vector<int> printListFromTailToHead(ListNode* head) { if(head!=NULL) { printListFromTailToHead(head->next); v.push_back(head->val); } return v; } };
class Solution2 { public: vector<int> printListFromTailToHead(ListNode* head) { vector<int> v; stack<int> s; while(head!=NULL) { s.push(head->val); head=head->next; } while(!s.empty()) { v.push_back(s.top()); s.pop(); } return v; } };
class Solution3 { public: vector<int> printListFromTailToHead(ListNode* head) { vector<int> v; while(head!=NULL) { v.push_back(head->val); head=head->next; } reverse(v.begin(),v.end()); return v; } };
int main() { ListNode *one=new ListNode(1); ListNode *two=new ListNode(2); ListNode *three=new ListNode(3); ListNode *four=new ListNode(4); ListNode *five=new ListNode(5); ListNode *six=new ListNode(6); one->next=two; two->next=three; three->next=four; four->next=five; five->next=six; six->next=NULL; Solution3 s; vector<int> v; v=s.printListFromTailToHead(one); int len=v.size(); for(int i=0;i<len;i++) cout<<v[i]<<' '; cout<<endl; return 0; }
|
参考链接:https://leetcode-cn.com/problems/cong-wei-dao-tou-da-yin-lian-biao-lcof/solution/mian-shi-ti-06-cong-wei-dao-tou-da-yin-lian-biao-d/