【Leetcode】链表的回文结构与相交链表

链表的回文结构

在这里插入图片描述
所谓回文结构通俗的讲就是链表的节点要关于中间的节点对称,那么如何判断是否对称呢,思路如下:
首先我们需找出链表中的中间节点,然后再将中间节点作为新的头节点来创建一个新的链表,往后的节点依次尾插到该头节点后,再将该新链表逆置,最后再将新链表与原链表做比较即可。
图示如下:
在这里插入图片描述

/*
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;
}
  • 40
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 22
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 22
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值