快乐学习每一天
一、链表相交
给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。
例如:
1.思路分析
链表相交,那就是两个链表的某个节点相同,指向了同一个地址。基本上有两个思路:
思路1:
直接暴力求解(穷举法)
\color{red}{直接暴力求解(穷举法)}
直接暴力求解(穷举法),依次取A链表中的节点和B链表的所有节点进行比较,如果遇到相同的节点,那就是相交。这个方法的时间复杂度O(N^2)。
思路2:
我们直接来遍历两个链表,如果尾节点相同,那么就是相交的
\color{red}{我们直接来遍历两个链表,如果尾节点相同,那么就是相交的}
我们直接来遍历两个链表,如果尾节点相同,那么就是相交的。因为我们还得返回相交的节点,所以还得想办法。
如果在相交前的节点数相同,那么我们可以直接分别往后走,相同的就是要找的节点。如果不同的话,因为前面我们遍历了链表,这里就可以求出它的长度,求出两链表的差,让长链表先走几步,然后再一起走,这样岂不是大功告成。
2.上手实验
代码示下:
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
struct ListNode*tailA,*tailB;
int lena=1,lenb=1,m=0;//初始1是因为找尾是tail->next
tailA=headA;
tailB=headB;
while(tailA->next)//找A链表的尾
{
lena++;
tailA=tailA->next;
}
while(tailB->next)//找B尾
{
lenb++;
tailB=tailB->next;
}
m=abs(lena-lenb);//求出相差的
//找相同节点
if(tailA!=tailB)
{
return NULL;
}
//相同则让长的链表先走相差的步数
struct ListNode*longlist=headA,*shortlist=headB;
if(lena<lenb)
{
longlist=headB;
shortlist=headA;
}
while(m--)//让长的先走
{
longlist=longlist->next;
}
//然后同时往后走
while(shortlist!=longlist)
{
longlist =longlist->next;
shortlist=shortlist->next;
}
return longlist;
}
这题就这样结束了,对于暴力求解想必大家都很清楚,我就不多赘述了。下一题来看链表分割。
二、链表分割
现有一链表的头指针 ListNode pHead,给一定值x,编写一段代码将所有小于x的结点排在其余结点之前,且不能改变原来的数据顺序,返回重新排列后的链表的头指针。*
1.分析题意
这道题目的意思就是以x为基准进行分割,且不能改变原本的顺序。我们用图画来帮助理解。
2.明析思路
比较简单的思路是开两个链表出来,一个放大的,一个放小的,最后再把两个链表连在一起。
最后要记得将自己开出来的哨兵卫free掉,最后一个节点的next要指向NULL,不然就陷入死循环了。
代码如下:
ListNode* partition(ListNode* pHead, int x) {
// write code here
//重新开两个链表
struct ListNode*lesshead,*lesstail,*greaterhead,*greatertail;
lesshead=lesstail=(struct ListNode*)malloc(sizeof(struct ListNode));
lesstail->next=NULL;
greaterhead=greatertail=(struct ListNode*)malloc(sizeof(struct ListNode));
greatertail->next=NULL;
struct ListNode*cur=pHead;
while(cur)//将不同类别的节点分好
{
if(cur->val<x)
{
lesstail->next=cur;
lesstail=cur;
}
else
{
greatertail->next=cur;
greatertail=cur;
}
cur=cur->next;
}
//链接
lesstail->next=greaterhead->next;//不是指向greaterhead
greatertail->next=NULL;
struct ListNode* newhead=lesshead->next;
free(lesshead);
free(greaterhead);
return newhead;
}
};
对于链表的题目,首先大家还是画画图比较好,帮助理解,理清思路再去写代码。今天就到这里了,希望大家三连支持。