P.S 非科班出身,对C++和算法较陌生,从入门开始,使用Leetcode平台,借鉴了很多前人的思路,博客仅为记录用。
本期打卡链表的三道题目:对应<剑指 Offer 06. 从尾到头打印链表><剑指 Offer 24. 反转链表><剑指 Offer 35. 复杂链表的复制>
问题10:从尾到头打印链表
问题描述:输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。
问题要求:无
解题思路:这道题的要求是返回每个节点的值,而不是返回反过来的链表:一个自然的思路是使用栈从头到尾保存链表的节点值,然后再从栈顶到栈底依次取出值。
代码:
/**
1. Definition for singly-linked list.
2. struct ListNode {
3. int val;
4. ListNode *next;
5. ListNode(int x) : val(x), next(NULL) {}
6. };
*/
class Solution {
public:
vector<int> reversePrint(ListNode* head) {
stack<int> temp;
vector<int> result;
int i = 0;
while (head != nullptr){
temp.push(head->val);
head = head->next;
}
while (!temp.empty()){
result.push_back(temp.top());
i=i+1;
temp.pop();
}
return result;
}
};
注意点:
- 栈的声明:
stack<int> temp;
数组的声明vector<int> result;
数组加入数值result.push_back(temp.top());
参考资料:
问题11:反转链表
问题描述:定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。
问题要求:无
解题思路:这道题相当于比上一题更进一步,一个思路是递归。
主要策略:递归
a->b->c->d->e要变成a<-b<-c<-d<-e
可以为
a<-(b<-c<-d<-e)
即为
而将a->b变为a<-b要经历的包括:
(1) a->b->a;
(2) a->nullptr;即b->a->nullptr.
从尾部开始递归。
代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* new_head;
ListNode* reverseList(ListNode* head) {
if (head == nullptr || head->next == nullptr){
return head; //给出终止条件
}
else{
new_head = reverseList(head->next);
head->next->next = head;
head->next = nullptr; //每一步都是head在变化
return new_head;
}
}
};
注意点:
- 递归的思想以及操作放置的位置还是要掌握好;
参考资料:
问题12:复杂链表的复制
问题描述:请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。
问题要求:无
解题思路:这道题主要是参考其他人的思路(很妙)。
首先复制一次:把a->b->c变成a->a’->b->b’->c->c’
这样相当于把链表的next这一属性定下来了(复制了a.b.c的顺序);
然后根据a.b.c的random属性,赋值a’.b’.c’的random属性;
最后把a’.b’.c’独立出来。
代码:
/*
// Definition for a Node.
class Node {
public:
int val;
Node* next;
Node* random;
Node(int _val) {
val = _val;
next = NULL;
random = NULL;
}
};
*/
class Solution {
public:
Node* copyRandomList(Node* head) {
if (head == nullptr){
return nullptr;
}
for (Node* node = head;node != nullptr;node = node->next->next) {
Node* newNode = new Node(node->val);
newNode->next = node->next;
node->next = newNode;
}
for (Node* node = head;node != nullptr;node = node->next->next) {
if(node->random != nullptr) {
Node* newNode = node->next;
newNode->random = node->random->next;
}
}
Node* new_head = head->next;
for (Node* node = head;node != nullptr;node = node->next) {
Node* newNode = node->next;
node->next = node->next->next;
newNode->next = (newNode->next != nullptr)? newNode->next->next:nullptr;
}
return new_head;
}
};
注意点:
- 这是个很有趣的思路,可以参考。
参考资料: