目录
给你一个链表的头节点 head
和一个整数 val
,请你删除链表中所有满足 Node.val == val
的节点,并返回 新的头节点 。
具体思路如下图所示
通过一个prev指针和cur指针,prev负责释放cur的元素时,将prev与cur的下一个元素链接起来,next负责保存cur的下一个地址
struct ListNode* removeElements(struct ListNode* head, int val)
{
struct ListNode*headguard=(struct ListNode*)malloc(sizeof(struct ListNode));//开辟一个哨兵位
headguard->next=head;
struct ListNode*prev=headguard;
struct ListNode*cur=head;
while(cur)//开始条件
{
if(cur->val==val)//迭代过程
{
struct ListNode*next=cur->next;
prev->next=next;
free(cur);
cur=next;
}
else
{
prev=cur;
cur=cur->next;
}
}
head=headguard->next;
free(headguard);//释放掉开辟的哨兵位
return head;
}
head
,请你反转链表,并返回反转后的链表。相当于通过创建一个newhead,然后把数据拿下来进行头插,然后进行重新置头返回新头节点.
struct ListNode* reverseList(struct ListNode* head)
{
struct ListNode*newhead=NULL;
struct ListNode*cur=head;
while(cur)
{
struct ListNode*next=cur->next;
cur->next=newhead;//将数据连载newhead上
newhead=cur; //重新置头
cur=next; 迭代
}
return newhead;
}
给定一个头结点为 head
的非空单链表,返回链表的中间结点。
如果有两个中间结点,则返回第二个中间结点。
struct ListNode* middleNode(struct ListNode* head)
{
struct ListNode*slow=head;
struct ListNode*fast=head;
while(fast&&fast->next)
{
slow=slow->next;
fast=fast->next->next;
}
return slow;
}
struct ListNode* FindKthToTail(struct ListNode* pListHead, int k )
{
struct ListNode*fast=pListHead;
struct ListNode*slow=pListHead;
while(k)
{
if(fast==NULL)
{
return NULL;
}
fast=fast->next;
k--;
}
while(fast)
{
slow=slow->next;
fast=fast->next;
}
return slow;
}
最后再判断一下链表一和链表二,那个还没插入完,再把没插入完的直接链接再新链表后面即可
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2)
{
if(list1==NULL)
{
return list2;
}
if(list2==NULL)
{
return list1;
}
struct ListNode*head=NULL;
struct ListNode*tail=NULL;
if(list1->valval)
{
head=list1;
tail=list1;
list1=list1->next;
}
else
{
head=list2;
tail=list2;
list2=list2->next;
}
while(list1&&list2)
{
if(list1->valval)
{
tail->next=list1;
list1=list1->next;
}
else
{
tail->next=list2;
list2=list2->next;
}
tail=tail->next;
}
if(list1!=NULL)
{
tail->next=list1;
}
if(list2!=NULL)
{
tail->next=list2;
}
return head;
}
class Partition {
public:
ListNode* partition(ListNode* pHead, int x)
{
struct ListNode*smallhead,*smalltail,*bighead,*bigtail;
smallhead=smalltail=(struct ListNode*)malloc(sizeof(struct ListNode));
bighead=bigtail=(struct ListNode*)malloc(sizeof(struct ListNode));
smalltail->next=NULL;
bigtail->next=NULL;
struct ListNode*cur=pHead;
while(cur)
{
if(cur->valnext=cur;
smalltail=smalltail->next;
}
else
{
bigtail->next=cur;
bigtail=bigtail->next;
}
cur=cur->next;
}
smalltail->next=bighead->next;
bigtail->next=NULL;
pHead=smallhead->next;
free(bighead);
free(smallhead);
return pHead;
}
};
测试样例:
1->2->2->1
返回:true
思路:通过找到中间节点,中间节点后面的数据进行逆置,然后迭代从中间节点开始,与链表的中间节点前进行比较,相等输出true,否则输出false
class PalindromeList {
public:
bool chkPalindrome(ListNode* A)
{
struct ListNode*slow=A;
struct ListNode*fast=A;
while(fast->next)
{
slow=slow->next;
fast=fast->next;
}
struct ListNode*change=NULL;
struct ListNode*head=slow;
while(head)
{
struct ListNode*next=slow->next;
head->next=change;
change=head;//重新置头
head=next;
}
while(slow)
{
if(A->val!=change->val)
{
return false;
}
slow=slow->next;
change=change->next;
}
return true;
}
};
headA
和 headB
,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null
。图示两个链表在节点 c1
开始相交:
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB)
{
if(headA==NULL||headB==NULL)
{
return NULL;
}
struct ListNode *list1=headA;
struct ListNode *list2=headB;
int lenA=0,lenB=0;
while(list1)//list1的长度
{
list1=list1->next;
lenA++;
}
while(list2)//list2的长度
{
list2=list2->next;
lenB++;
}
if(list1!=list2) /如果最后不相等
{
return NULL;
}
struct ListNode *shortlist=headA;
struct ListNode *longlist=headB;
if(lenA>lenB)//链表长度比较
{
shortlist=headB;
longlist=headA;
}
int gap=abs(lenA-lenB);
while(gap--)
{
longlist=longlist->next;
}
while(shortlist!=longlist)//找相同节点
{
shortlist=shortlist->next;
longlist=longlist->next;
}
return longlist;
}
head
,判断链表中是否有环。如果链表中有某个节点,可以通过连续跟踪 next
指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos
来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos
是 -1
,则在该链表中没有环。注意:pos
不作为参数进行传递,仅仅是为了标识链表的实际情况。
如果链表中存在环,则返回 true
。 否则,返回 false
。
bool hasCycle(struct ListNode *head)
{
if(head==NULL)
{
return false;
}
struct ListNode *slow=head;
struct ListNode *fast=head;
while(fast&&fast->next)
{
fast=fast->next->next;
slow=slow->next;
if(fast==slow)
{
return true;
}
}
return false;
}
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况不允许修改链表。
struct ListNode *detectCycle(struct ListNode *head)
{
struct ListNode *slow=head;
struct ListNode *fast=head;
if(fast==NULL||fast->next==NULL)
{
return NULL;
}
while(fast&&fast->next)
{
slow=slow->next;
fast=fast->next->next;
if(fast==slow)
{
struct ListNode *meet=fast;
while(meet!=head)
{
head=head->next;
meet=meet->next;
}
return meet;
}
}
return NULL;
}
给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点。构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的 next 指针和 random 指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点。
struct Node* copyRandomList(struct Node* head)
{
if(head==NULL)
{
return NULL;
}
struct Node*cur=head;
while(cur)
{
struct Node*next=cur->next;
struct Node*copy=(struct Node*)malloc(sizeof(struct Node));
copy->val=cur->val;
copy->next=next;
cur->next=copy;
cur=next;
}
//处理random
cur=head;
while(cur)
{
struct Node*copy=cur->next;
if(cur->random==NULL)
{
copy->random=NULL;
}
else
{
copy->random=cur->random->next;
}
cur=copy->next;
}
//把链表拿出来
cur=head;
struct Node*copyhead,*copytail;
copyhead=copytail=(struct Node*)malloc(sizeof(struct Node));
while(cur)
{
struct Node*copy=cur->next;
struct Node*next=copy->next;
copytail->next=copy;
copytail=copytail->next;
cur->next=next;
cur=next;
}
struct Node*guard=copyhead;
copyhead=copyhead->next;
free(guard);
return copyhead;
}
struct ListNode* insertionSortList(struct ListNode* head)
{
if(head==NULL||head->next==NULL)
return head;
struct ListNode*sorthead=head;
struct ListNode*cur=head->next;
sorthead->next=NULL;
while(cur)//开始条件
{
struct ListNode*next=cur->next;
struct ListNode*p=NULL;
struct ListNode*c=sorthead;
while(c)
{
if(cur->valval)//有小于的数据在在循环外处理
{
break;
}
else
{
p=c;
c=c->next;
}
}
if(p==NULL)
{
cur->next= c;
sorthead=cur;
}
else
{
p->next=cur;
cur->next=c;
}
cur=next;
}
return sorthead;
}
特殊情况
struct ListNode* deleteDuplication(struct ListNode* pHead )
{
struct ListNode*fast=pHead->next;
struct ListNode*slow=pHead;
struct ListNode* prev=NULL;
if(pHead==NULL)
{
return NULL;
}
else
{
while(fast)
{
if(fast->val!=slow->val)
{
prev=slow;
fast=fast->next;
slow=slow->next;
}
else
{
while((fast!=NULL)&&(slow->val==fast->val))
{
fast=fast->next;
if(prev==NULL)
{
pHead=fast;
}
else
{
prev->next=fast;
}
}
while(slow!=fast)
{
struct ListNode*p=slow;
slow=slow->next;
free(p);
}
if(fast!=NULL)
{
fast=fast->next;
}
}
}
}
return pHead;
}