链表的回文结构
所谓回文结构通俗的讲就是链表的节点要关于中间的节点对称,那么如何判断是否对称呢,思路如下:
首先我们需找出链表中的中间节点,然后再将中间节点作为新的头节点来创建一个新的链表,往后的节点依次尾插到该头节点后,再将该新链表逆置,最后再将新链表与原链表做比较即可。
图示如下:
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};*/
struct ListNode* FindMideNode(struct ListNode*phead) //运用快慢指针的方法找到中间节点
{
struct ListNode*slow,*fast;
slow=fast=phead;
while(fast&&fast->next)
{
slow=slow->next;
fast=fast->next->next;
}
return slow;
}
struct ListNode* reverseList(struct ListNode*phead) //逆置就是将原节点头插到新链表中
{
struct ListNode*newhead=NULL;
struct ListNode*cur=phead;
while(cur)
{
struct ListNode*Next=cur->next;
cur->next=newhead;
newhead=cur;
cur=Next;
}
return newhead;
}
bool chkPalindrome(ListNode* A) {
struct ListNode*midNode= FindMideNode(A); //找到链表的中间节点
struct ListNode* rhead=reverseList(midNode); //对链表逆置
while(A && rhead)
{
if(A->val != rhead->val) //比较两链表对应节点的值
{
return false;
}
else
{
A=A->next;
rhead=rhead->next;
}
}
return true;
}
相交链表
思路:因为我们不清楚在相交的节点前两链表分别有几个节点,所以我们需要计算出给出的链表 headA 与链表 headB 的长度,并且求出两个链表的长度差;为了保证遍历两个链表时同时到达相交的节点,所以需要在遍历到相交节点时定义的指针走的长度一样,所以我们就需要先遍历较长的链表,使其向前遍历 gap 的长度(即两链表长度差),最后若在遍历过程中两链表首次遇到了相同的节点,那么说明这两个链表相交,该节点就为相交的起始节点,否则不相交。
代码实现如下:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
struct ListNode *curA=headA;
struct ListNode *curB=headB;
struct ListNode*longList=headA; //假设headA为长的链表
struct ListNode*shortList=headB; //假设headB为短的链表
int lenA,lenB;
lenA=lenB=0;
while(curA) //遍历headA
{
curA=curA->next;
lenA++;
}
while(curB) //遍历headB
{
curB=curB->next;
lenB++;
}
if(lenA<lenB) //若与上面的假设不一致,调整回来即可
{
shortList=headA;
longList=headB;
}
int gap=abs(lenA-lenB);
while(gap--) //使长的链表先走gap步长
{
longList=longList->next;
}
while(longList && shortList)
{
if(longList==shortList) //当节点相等时,则说明链表相交
{
return longList; //返回相交的起始节点
}
else
{
longList=longList->next;
shortList=shortList->next;
}
}
return NULL;
}