方法一:三指针法
struct ListNode* reverseList(struct ListNode* head) {
struct ListNode*left=head,*right=NULL;
if(head==NULL||head->next==head)
{
return head;
}
while(left)
{
struct ListNode*cur=left->next;
left->next=right;
right=left;
left=cur;
}
return right;
}
方法二:建立一个新的头节点,然后进行头插
struct ListNode* reverseList(struct ListNode* head) {
struct ListNode*cur=head;
if(head==NULL)
{
return NULL;
}
struct ListNode*newhead=(struct ListNode*)malloc(sizeof(struct ListNode));
newhead->val=head->val;
newhead->next=NULL;
while(cur)
{
struct ListNode*copy=(struct ListNode*)malloc(sizeof(struct ListNode));
copy->val=cur->val;
copy->next=newhead->next;
newhead->next=copy;
cur=cur->next;
}
return newhead->next;
}
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {
struct ListNode*head=(struct ListNode*)malloc(sizeof(struct ListNode));
struct ListNode*cur1=list1;
struct ListNode*cur2=list2;
struct ListNode*tail=NULL;
while(cur1&&cur2)
{
if(cur1->val>=cur2->val)
{
if(tail==NULL)
{
head=tail=cur2;
cur2=cur2->next;
}
else
{
tail->next=cur2;
tail=tail->next;
cur2=cur2->next;
}
}
else if(cur1->val<cur2->val)
{
if(tail==NULL)
{
head=tail=cur1;
cur1=cur1->next;
}
else
{
tail->next=cur1;
tail=tail->next;
cur1=cur1->next;
}
}
}
if(cur1==NULL&&cur2!=NULL)
{
if(tail==NULL)
{
head=tail=cur2;
}
else
{
tail->next=cur2;
}
}
else if(cur1!=NULL&&cur2==NULL)
{
if(tail==NULL)
{
head=tail=cur1;
}
else
{
tail->next=cur1;
}
}
else
{
if(tail==NULL)
{
return NULL;
}
else
{
tail->next=NULL;
}
}
return head;
}
方法一:分别建立两个新链表,分别进行尾插,最后组合成一条符合要求的总链表
需要注意的是尾指针要置空,否则它的最后一个节点的next指向仍可能为小于x的值,出现无法读取内存的错误
class Partition {
public:
ListNode* partition(ListNode* pHead, int x) {
struct ListNode* cur=pHead;
struct ListNode* tail=nullptr;
struct ListNode*ptail=nullptr;
struct ListNode*head=nullptr;
struct ListNode*newhead=nullptr;
while(cur)
{
if(cur->val<x)
{
if(tail==nullptr)
{
newhead=cur;
tail = cur;
}
else
{
tail->next=cur;
tail=tail->next;
}
}
else
{
if(ptail==nullptr)
{
head=cur;
ptail = cur;
}
else
{
ptail->next=cur;
ptail=ptail->next;
}
}
cur=cur->next;
}
if(newhead)
{
if(head)
{
tail->next=head;
ptail->next=NULL;
}
return newhead;
}
else
{
if(head)
{
ptail->next=NULL;
}
return head;
}
}
方法二:建立带哨兵位的头结点,避免空指针带来的麻烦
class Partition {
public:
ListNode* partition(ListNode* pHead, int x) {
struct ListNode*newhead=(struct ListNode*)malloc(sizeof(struct ListNode));
struct ListNode*head=(struct ListNode*)malloc(sizeof(struct ListNode));
struct ListNode*tail=newhead;
struct ListNode*ptail=head;
struct ListNode*cur=pHead;
while(cur)
{
if(cur->val<x)
{
tail->next=cur;
tail=cur;
}
else
{
ptail->next=cur;
ptail=cur;
}
cur=cur->next;
}
ptail->next=NULL;
tail->next=head->next;
return newhead->next;
}
方法:与上述反转链表题目有相似之处,反转后再一一比较,博主这里用的反转链表的方法二,建议使用方法一的三指针法从而简化代码
class PalindromeList {
public:
bool chkPalindrome(ListNode* A) {
// write code here
struct ListNode*cur=A,*head=A;
if(cur==NULL)
{
return false;
}
struct ListNode*newhead=(struct ListNode*)malloc(sizeof(struct ListNode));
newhead->val=head->val;
newhead->next=NULL;
while(cur)
{
struct ListNode*copy=(struct ListNode*)malloc(sizeof(struct ListNode));
copy->val=cur->val;
copy->next=newhead->next;
newhead->next=copy;
cur=cur->next;
}
struct ListNode*cur2=newhead->next;
struct ListNode*cur1=head;
while(cur1&&cur2)
{
if(cur1->val==cur2->val)
{
cur1=cur1->next;
cur2=cur2->next;
}
else
{
return false;
}
}
return true;
}
博主写这些题目花了很长时间,有很多的收获,解决这些链表题有一个好的解题思路会事半功辈,多思考一些方法对以后的解这种类似的题也会有很大的帮助,大家一起加油!