【简单】Leetcode相交链表///巧妙思路///普通写法

编写一个程序,找到两个单链表相交的起始节点。
如下面的两个链表:
在节点 c1 开始相交。
示例 1:

输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
输出:Reference of the node with value = 8
输入解释:相交节点的值为 8 (注意,如果两个列表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。

示例 2:
在这里插入图片描述
输入:intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1
输出:Reference of the node with value = 2
输出解释:相交节点的值为2.

示例 3:

输入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2
输出:null
解释:两链表不相交所以输出null。

1.普通做法
因为两个链表只要有一个节点相等,之后就都相同,如上几张图所示。所以普通做法的思路就是想让两链表相交节点前不等长的地方右对齐,用两个指针从等长的地方开始遍历,若存在相同的点则返回那个点,否则平行。

class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        ListNode *longlist,*shortlist;
        ListNode *p = headA,*q = headB;
        int dist=0;
        int Len1 = 0;
        int Len2 = 0;
        
        while(p){  //两个while用于记录A,B的链表表长
            ++Len1;
            p = p -> next;
        }
        while(q){
            ++Len2;
            q = q -> next;
        }
        
        if(Len1 > Len2)  //这个if用于将长短表的差值赋给dist
        {
            longlist = headA->next;
            shortlist = headB->next;
            dist = Len1 - Len2;
        }else
        {
            longlist = headB->next;
            shortlist = headA->next;
            dist = Len2 - Len1;
        }
        while(dist && longlist != NULL) //执行循环直到dist等于0,意思就是让长表的指针指向对应短表表头的位置,即对齐
        {
            longlist = longlist->next;
        }
        while(longlist != NULL) //这里写shortlist也可以,因为已经对齐了
        {
            if(longlist->val == shortlist->val) //如果存在相同的节点,说明有交点,返回这个节点
            {
                    return longlist;
            }else
            {
                longlist = longlist->next;
                shortlist = shortlist->next;
            }
        }
        return NULL; //结束了while循环,说明没有相同的节点,也就是说两链表平行,所以return NULL
        
    }
};

2.巧妙做法
先上图
比如一个相交链表A前面有4个节点,相交及相交后有3个节点;B相交前有2个节点,相交后有3个节点。B遍历完一共遍历了5个节点,再从A一直遍历到相交节点一共便利了5+5=10个,而A遍历完一共遍历了7个节点,再从B遍历到相交节点,一共遍历了7+3=1个。因为路程是一样的,所以最后肯定会遍历到相交节点。

public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
    if (headA == null || headB == null) return null; //如果有一个为空,则返回空
    ListNode pA = headA, pB = headB;
    while (pA != pB) {
        pA = pA == null ? headB : pA.next; //如果pA不为空则指向pA下一个,为空则从headB开始遍历,下同
        pB = pB == null ? headA : pB.next;
    }
    return pA;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值