〇、目录
一、反转链表
1、简单版:反转全部节点
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* newhead=NULL;
while(head)
{
ListNode* nex=head->next;
head->next=newhead;
newhead=head;
head=nex;
}
return newhead;
}
};
2、进阶版:从指定节点到指定节点反转
class Solution {
public:
ListNode* reverseBetween(ListNode* head, int m, int n) {
int change_len=n-m+1;
ListNode* pre_head=NULL;
ListNode* result=head;
while(head && --m)
{
pre_head=head;
head=head->next;
}
ListNode* modify_list_tail=head;
ListNode* newnode=NULL;
while(head && change_len)
{
ListNode* nex=head->next;
head->next=newnode;
newnode=head;
head=nex;
change_len--;
}
modify_list_tail->next=head;
if(pre_head)
{
pre_head->next=newnode;
}
else
{
result=newnode;
}
return result;
}
};
二、求两个链表的交点
法一、使用STL——set
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
std::set<ListNode*> node_set;
while(headA)
{
node_set.insert(headA);
headA=headA->next;
}
while(headB)
{
if(node_set.find(headB)!=node_set.end())
{
return headB;
}
headB=headB->next;
}
return NULL;
}
};
法二、双指针
class Solution {
public:
int len(ListNode* node)
{
int length=0;
while(node)
{
node=node->next;
length++;
}
return length;
}
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode* longnode;
ListNode* shortnode;
int dis=0;
int len1=len(headA);
int len2=len(headB);
if(len1>len2)
{
longnode=headA;
shortnode=headB;
dis=len1-len2;
}
else
{
longnode=headB;
shortnode=headA;
dis=len2-len1;
}
while(dis)
{
longnode=longnode->next;
dis--;
}
while(longnode && shortnode && longnode!=shortnode)
{
longnode=longnode->next;
shortnode=shortnode->next;
}
return longnode;
}
};
三、链表求环
1、简单版:判断链表是否有环
class Solution {
public:
bool hasCycle(ListNode *head) {
ListNode* fast=head;
ListNode* slow=head;
if(head==NULL)
{
return false;
}
while(fast && fast->next)
{
fast=fast->next->next;
slow=slow->next;
if(fast==slow)
{
return true;
}
}
return false;
}
};
2、进阶版:找出环的起始节点
法一、使用STL—set
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
std::set<ListNode*> node_set;
while(head)
{
if(node_set.find(head)!=node_set.end())
{
return head;
}
node_set.insert(head);
head=head->next;
}
return NULL;
}
};
法二、快慢指针
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode* fast=head;
ListNode* slow=head;
ListNode* meet=NULL;
if(!head)
{
return NULL;
}
while(fast && fast->next)
{
fast=fast->next->next;
slow=slow->next;
if(fast==slow)
{
meet=fast;
break;
}
}
if(meet==NULL)
{
return NULL;
}
while(head && meet)
{
if(head==meet)
{
return head;
}
head=head->next;
meet=meet->next;
}
return NULL;
}
};
四、链表划分
使用临时头节点:
class Solution {
public:
ListNode* partition(ListNode* head, int x) {
ListNode less_head(0);
ListNode more_head(0);
ListNode* less_ptr=&less_head;
ListNode* more_ptr=&more_head;
while(head)
{
if(head->val < x)
{
less_ptr->next=head;
less_ptr=head;
}
else
{
more_ptr->next=head;
more_ptr=head;
}
head=head->next;
}
less_ptr->next=more_head.next;
more_ptr->next=NULL;
return less_head.next;
}
};
五、复杂链表的深度拷贝
class Solution {
public:
Node* copyRandomList(Node* head) {
std::map<Node*,int> node_map;
std::vector<Node*> node_vec;
int i=0;
Node* ptr=head;
while(ptr)
{
node_vec.push_back(new Node(ptr->val));
node_map[ptr]=i;
ptr=ptr->next;
i++;
}
node_vec.push_back(0);
ptr=head;
i=0;
while(ptr)
{
node_vec[i]->next=node_vec[i+1];
if(ptr->random)
{
int rid=node_map[ptr->random];
node_vec[i]->random=node_vec[rid];
}
ptr=ptr->next;
i++;
}
return node_vec[0];
}
};
六、合并排序链表
1、简单版:2个排序链表
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
if(!l1)
{
return l2;
}
if(!l2)
{
return l1;
}
if(l1->val < l2->val)
{
l1->next=mergeTwoLists(l1->next, l2);
return l1;
}
else
{
l2->next=mergeTwoLists(l1, l2->next);
return l2;
}
}
};
2、进阶版:K个排序链表
方法一、所有节点放到一个vector里,调用sort函数排序。
bool cmp(ListNode* p1, ListNode* p2)
{
return p1->val<p2->val;
}
class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
std::vector<ListNode*> node_vec;
for(int i=0;i<lists.size();i++)
{
ListNode* head=lists[i];
while(head)
{
node_vec.push_back(head);
head=head->next;
}
}
if(node_vec.size()==0) return NULL;
std::sort(node_vec.begin(),node_vec.end(),cmp);
for(int i=1;i<node_vec.size();i++)
{
node_vec[i-1]->next=node_vec[i];
}
node_vec[node_vec.size()-1]->next=NULL;
return node_vec[0];
}
};
方法二、分制
class Solution {
public:
ListNode* merge2lists(ListNode* l1,ListNode* l2)
{
if(!l1)
{
return l2;
}
if(!l2)
{
return l1;
}
if(l1->val < l2->val)
{
l1->next=merge2lists(l1->next,l2);
return l1;
}
else
{
l2->next=merge2lists(l1,l2->next);
return l2;
}
}
ListNode* mergeKLists(vector<ListNode*>& lists) {
if(lists.size()==0)
return NULL;
if(lists.size()==1)
return lists[0];
if(lists.size()==2)
return merge2lists(lists[0],lists[1]);
std::vector<ListNode*> l1_vec;
std::vector<ListNode*> l2_vec;
int mid=lists.size()/2;
for(int i=0;i<mid;i++)
{
l1_vec.push_back(lists[i]);
}
for(int i=mid;i<lists.size();i++)
{
l2_vec.push_back(lists[i]);
}
ListNode* l1=mergeKLists(l1_vec);
ListNode* l2=mergeKLists(l2_vec);
return merge2lists(l1,l2);
}
};