开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 28 天,点击查看活动详情
Day05 2023/03/03
难度:简单
题目
输入一个链表的头节点,按链表从尾到头的顺序返回每个节点的值(用数组返回)。 如输入L,2,3的链表如下图:
返回一个数组为(3,2,1) 0<=链表长度<=10000
示例1
输入: 1 2 3 4 5 6
输出: 6 5 4 3 2 1
运行实例
思路
本题的意思就是让我们翻转链表,那我们采用带虚拟头节点的头插法创建链表,众所周知头插法创建的链表中数据和我们输入的数据是相反的。天然的就翻转了链表,代码也比较简单,当然这算是曲线救国的方式,大概不是本题的初衷,这里我也给出直接翻转链表的题解:206.反转链表。
关键点
- 本题也没啥关键点,可能用虚拟头节点的方式统一插入操作,需要注意一下。
- 包括后面释放虚拟头节点内存的小细节。
算法实现
c++代码实现-头插法翻转
#include <iostream>
using namespace std;
//定义链表节点
typedef struct LNode {
int data; // 数据域
LNode *next; // 指针域
LNode(int val) : data(val), next(nullptr){}; // 构造函数
} LNode, *ListLink;
// 采用带虚拟头节点的头插法创建链表,用空格隔开各个节点数据,回车结束链表创建
ListLink ListHeadInsert() {
LNode *dummyHead = new LNode(-1), *s, *tmp; // 虚拟头节点(统一插入操作) 待插入新节点指针 临时节点指针
int val;
char ch; // 待插入节点的数据
while (cin >> val) {
s = new LNode(val); // 创建待插入的新节点
s->next = dummyHead->next; // 插入节点
dummyHead->next = s;
if ((ch = cin.get()) == '\n') break; // 结束条件
};
tmp = dummyHead->next; // 真正的头节点
delete dummyHead; // 释放虚拟头节点
return tmp; // 返回真正的头节点
}
// 测试一下
int main() {
ListLink L = ListHeadInsert(); // 创建链表
LNode *cur = L; // 遍历指针
while (cur) { // 遍历打印节点
cout << cur->data << ' ';
cur = cur->next;
}
return 0;
}
- 时间复杂度 --- 创建链表的时间复杂度为
- 空间复杂度 --- 链表属于必要空间,除此无额外的辅助空间
总结
- 对数据结构中的一些基本操作,一定要熟悉,不要 "眼高手低"。