难度 较难 OJ链接
这里回文的意思就是对称。但单链表不能从后往前,所以我们该怎么做呢?
解题思路:
1.先求出中间节点
2.让中间节点后面的节点反转
3.最后开头和中间位置开始比较,当为NULL时,如果都一样就是回文。
偶数情况:
奇数情况:
那这里该怎么比呢?其实和上面的一样。
因为虽然后面的节点反转了,但是2的后面还是3,当rHead指向3时,2也正好指向3。
因为在前面的文章中,我已经写过反转和求中间节点的函数,这里就不在写了。
//求中间节点
struct ListNode* middleNode(struct ListNode* head){
struct ListNode* fast=head;
struct ListNode* slow=head;
while(fast&&fast->next)
{
fast=fast->next->next;
slow=slow->next;
}
return slow;
}
//反转链表
struct ListNode* reverseList(struct ListNode* head){
if(head==NULL)
return head;
struct ListNode* newhead=NULL;
struct ListNode* cur=head;
struct ListNode* next=cur->next;
while(cur)
{
cur->next=newhead;
newhead=cur;
cur=next;
if(cur)
next=cur->next;
}
return newhead;
}
//一一比较
bool chkPalindrome(ListNode* A) {
struct ListNode* mid=middleNode(A);
struct ListNode* rHead=reverseList(mid);
while(rHead)
{
if(rHead->val!=A->val)
{
return false;
}
else
{
A=A->next;
rHead=rHead->next;
}
}
return true;
}
难度 简单 OJ链接
首先,我们要知道什么是链表的相交?
链表的相交是Y型,不是X型。
为什么不能是X型呢?
因为这是一个单链表,相交结点后只能有一个后继,而X型就有两个后继了。所以不符合要求。
我们要找到第一个相交节点,我们要先判断它们是否相交。
那我们该如何判断它们是否相交呢?
思路1:
A链表每个结点地址跟B链表依次比较,如果有相等,就是相交,第一个相等就是交点。这个思路的时间复杂度为O(M*N),但它把第一个结点也顺便解决了。
思路2:
我们可以直接判断它们的尾节点地址是否相同,相同就说明它们相交,不同就说明不相交。这样思路的时间复杂度为O(M+N)。
然后,我们该如何找到第一个相交节点?
思路:
先求出两个链表的长度La,Lb,长的先走它们的差值|La-Lb|,然后再一起走,第一个地址相等的就是交点。
代码如下:
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
struct ListNode *tailA=headA,*tailB=headB;
//从1开始,因为我们下面只找到尾节点,少算一个
int lenA=1;
int lenB=1;
int dval=0;//记录差距步是多少
//找A链表的尾节点
while(tailA->next)
{
tailA=tailA->next;
lenA++;
}
//找B链表的尾节点
while(tailB->next)
{
tailB=tailB->next;
lenB++;
}
if(tailA!=tailB)
{
return NULL;
}
else
{
//相交,长的链表先走差距步
if(lenA>lenB)
{
dval=lenA-lenB;
while(dval--)
{
headA=headA->next;
}
}
else
{
dval=lenB-lenA;
while(dval--)
{
headB=headB->next;
}
}
//然后一起走
while(headB!=headA)
{
headA=headA->next;
headB=headB->next;
}
}
return headB;
}
也可以这样写:
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
struct ListNode *tailA=headA,*tailB=headB;
//从1开始,因为我们下面只找到尾节点,少算一个
int lenA=1;
int lenB=1;
//找A链表的尾节点
while(tailA->next)
{
tailA=tailA->next;
lenA++;
}
//找B链表的尾节点
while(tailB->next)
{
tailB=tailB->next;
lenB++;
}
//不相交,返回NULL
if(tailA!=tailB)
{
return NULL;
}
struct ListNode *shortList=headA,*longList=headB;
if(lenA>lenB)
{
longList=headA;
shortList=headB;
}
int gap=abs(lenB-lenA);
//长的链表走差距步
while(gap--)
{
longList=longList->next;
}
while(longList!=shortList)
{
longList=longList->next;
shortList=shortList->next;
}
return longList;
}
好了,到这里,这两题就结束了,如果大家觉得有帮助可以点点赞,支持一下啦!