【小菜鸡刷题记】---链表篇
剑指 Offer 06. 从尾到头打印链表
剑指 Offer 06. 从尾到头打印链表
输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。
输入:head = [1,3,2]
输出:[2,3,1]
反转实现
class Solution {
public:
vector<int> reversePrint(ListNode* head) {
vector<int> v;
ListNode* cur=head;
while(cur)
{
v.push_back(cur->val);
cur=cur->next;
}
reverse(v.begin(),v.end());
return v;
}
};
利用栈的特性
class Solution {
public:
vector<int> reversePrint(ListNode* head) {
vector<int> v;
stack<int> st;
ListNode* cur=head;
while(cur)
{
st.push(cur->val);
cur=cur->next;
}
while(!st.empty())
{
int top=st.top();
v.push_back(top);
st.pop();
}
return v;
}
};
递归实现
class Solution {
public:
vector <int> v;
vector<int> reversePrint(ListNode* head) {
// vector <int> v;
// if(head==nullptr)
// {
// return v;
// }
// v=reversePrint(head->next);
// v.push_back(head->val);
// return v;
vector<int> v;
if(head!=nullptr)
{
if(head->next!=nullptr)
{
v=reversePrint(head->next);
}
v.push_back(head->val);
}
return v;
}
};
剑指 Offer 24. 反转链表
剑指 Offer 24. 反转链表
定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。
示例:
输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL
头插法
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* newhead=nullptr;
ListNode* cur=head;
while(cur)
{
//保存下一个节点
ListNode* next=cur->next;
cur->next=newhead;
newhead=cur;
cur=next;
}
return newhead;
}
};
剑指 Offer 35. 复杂链表的复制
剑指 Offer 35. 复杂链表的复制
请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。
在我另一篇文章中有关于第二种方法的详解
示例 1: 输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]
哈希
以空间换时间:复制原链表中的节点N’,与原节点构成键值对<N,N’>添加到map集合中,然后递归复制下一节点和随机指针
class Solution {
public:
unordered_map<Node*,Node*> map;
Node* copyRandomList(Node* head) {
if(head==nullptr)
{
return nullptr;
}
if(map.count(head)<1)
{
Node* copyNode=new Node(head->val);
//map.insert({head,copyNode});
map.insert(std::make_pair(head,copyNode));//添加到map中
copyNode->next=copyRandomList(head->next);//递归复制下一节点
copyNode->random=copyRandomList(head->random);///递归复制随机指针
}
return map[head];//返回pair.second的引用
}
};
迭代+节点拆分
/*
// 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:
//1.复制原链表的每个节点并添加的原节点的下一节点
void copyNodeAndNext(Node* head)
{
Node* cur=head;
while(cur)
{
Node* copyNode=new Node(cur->val);
copyNode->next=cur->next;
cur->next=copyNode;
cur=copyNode->next;
}
}
//2.复制原链表节点的随机指针
void copyNodeAndRandom(Node* head)
{
Node* cur=head;
while(cur)
{
Node* copyNode=cur->next;
//如果原链表的随机指针不为空,那么复制节点的随机指针指向的节点
//就是原链表随机指针指向节点的下一个节点
if(cur->random)
{
copyNode->random=cur->random->next;
}
cur=copyNode->next;
}
}
//3.将复制好的链表拆下来
Node* deatchList(Node* head)
{
Node* cur=head;
Node* copyhead=new Node(-1);//创建头结点,方便拆分组合
Node *copytail=copyhead;
while(cur)
{
Node* copyNode=cur->next;
Node* next=copyNode->next;
//保留原链表
cur->next=next;
//分割出新链表
copytail->next=copyNode;
copytail=copytail->next;
cur=next;
}
Node* newhead=copyhead->next;
delete copyhead;
return newhead;
}
Node* copyRandomList(Node* head) {
copyNodeAndNext(head);
copyNodeAndRandom(head);
return deatchList(head);
}
};