[剑指Offer笔记]5_链表 printListFromTailToHead
链表的一些操作
- 链表的创建 / 插入节点 / 删除节点
- 插入节点: 新建一个节点,分配空间!!!
Example 1 往链表末尾添加一个节点
// 添加一个节点到链表的末尾
void AddToTail(ListNode **pHead, int value) {
ListNode *pNew = new ListNode();
pNew->val = value;
pNew->next = NULL;
if (*pHead == NULL) {
*pHead = pNew;
} else {
ListNode *pNode = *pHead;
while (pNode->next != NULL) {
pNode = pNode->next;
}
pNode->next = pNew;
}
}
Example 2 在链表中查找第一个含有某个值的节点,并删除
void RemoveNode(ListNode** pHead, int value) {
if (pHead == NULL || *pHead == NULL)
return;
// 添加辅助的头节点
ListNode *pre = new ListNode();
pre->val = 0;
pre->next = *pHead;
ListNode *pNode = *pHead;
while (pNode != NULL&& pNode->val != value) {
pre = pNode;
pNode = pNode->next;
}
ListNode *pNodeToBeDelete = pNode;
pre->next = pNode->next;
delete pNodeToBeDelete;
}
题目描述:
- 输入一个链表,按链表值从尾到头的顺序返回一个ArrayList。
分析:
- 方法一: 从尾到头. 可以考虑用栈实现
- 方法二: 可以考虑用递归实现
实现1:
namespace pro5_1 {
// 翻转一下.
class Solution {
public:
vector<int> printListFromTailToHead(ListNode* head) {
vector<int> result;
if (head == NULL) {
return result;
}
ListNode *pNode = head;
while (pNode != NULL) {
result.push_back(pNode->val);
pNode = pNode->next;
}
reverse(result.begin(), result.end());
return result;
}
};
}
实现2:
namespace pro5_2 {
// 递归的方法:
class Solution {
private:
vector<int> result = {};
void helper(ListNode* head) {
if (head != NULL) {
helper(head->next);
result.push_back(head->val);
}
}
public:
vector<int> printListFromTailToHead(ListNode* head) {
helper(head);
return result;
}
};
}
做题体会:
-
注意:链表需要作为函数参数输入
使用 指针的指针 or 指针的引用 !!!
-
使用 一个 假的头指针 可以去除一些 Head 的特殊判断