LeetCode刷题笔记(Intersection of Two Linked Lists)

继续刷链表的题,感觉还是有一定的棘手,下面和大家来分享一下经验吧!

题目如下:

 

题意分析: 

给定两个单链表,找到它们的公共交点,并返回第一个交点的值。

注:①如果两个链表没有交点,则返回NULL。

       ②操作过程中应该保留两链表的原始结构

       ③两链表均不为环状链表

       ④算法要求的时间复杂度为O(n),空间复杂度为O(1)。

解答如下:

方法一(“右对齐”比较)

分别遍历两个链表,计算得到各自的长度,然后求它们长度的差值,如果长度相等则对应位置一一比较即可,否则需将较长的那个链表的头指针向后移动这个差值的个数,再一一比较即可。

注:由于链表重叠部分是公共的,所以只需要判断指向第一个公共节点的指针是否相等就行,而不是去判断他们的 ->val 是否相等。

class Solution{
public:
    ListNode *getIntersectionNode( ListNode *headA, ListNode *headB ) {
        ListNode *curA = headA;
        ListNode *curB = headB;
        int lenA = GetLength(headA);                   //计算链表长度
        int lenB = GetLength(headB);
        if (!lenA || !lenB)                            //存在空链表则返回NULL
            return NULL;
        if (lenA < lenB) {                             //比较长度,并移动对应指针
            for (int i = 0; i < lenB - lenA; i++)
                curB = curB->next;
        } else if (lenA > lenB) {
            for (int i = 0; i < lenA - lenB; i++)
                curA = curA->next;
        }
        while (curA != NULL && curB != NULL && curA != curB)    //比较对应位置的值
        { curA = curA -> next;
          curB = curB -> next;}
        if (curA != NULL && curB != NULL)
            return curA;
        else
            return NULL;
    }
    int GetLength( ListNode *head ){                    //计算链表长度函数
        int count = 0;
        while( head ){
            count ++;
            head = head -> next;
        }
        return count;
    }
};

 

提交后的结果如下:

 

方法二(用链表的环形思想) 

先让两条链表分别从各自的开头开始往后遍历,当其中一条遍历到末尾时,再让其跳到另一个条链表的开头继续遍历。两个指针最终会相等,而且只有两种情况,一种情况是在公共交点处相遇,另一种情况是在各自的末尾的空节点处相等。由于两个指针走过的路程相同,且为两个链表的长度之和,所以必然相等。

class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        if( !headA || !headB )  return NULL;

        ListNode *a = headA;
        ListNode *b = headB;

        while(a!=b){
            a = a == NULL?headB : a->next;//当找到表A的尾部时,a就开始指向表B
            b = b == NULL?headA : b->next;//b也一样,这样一定有一个先指向另一个表,也就使得二者的长度之差得到了补偿
            //画一个链表图就非常的直观了
            //第二轮迭代时,a和b所要遍历的剩余节点的数量都是一样的
            //因此即使没有交集,当a遍历到结尾的NULL时,返回值也是正确的
        }
        return a;
    }
};

 

 提交后的结果如下:

 

方法三(用哈希表法) 

先创建一个哈希表,其键为节点的指针,其值记录出现的指针(出现记为1,未出现记为0)。遍历一遍A表,用哈希表记录各节点指针,然后再遍历一遍B表,尝试找到第一公共节点指针,若没找到则返回NULL。

class Solution{
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB){
        unordered_map< ListNode * , int> record;
        ListNode *a = headA;
        ListNode *b = headB;
        while( a != NULL )             //哈希表存储A链节点指针
        {
            record[a] = 1;
            a = a -> next;
        }
        while( b != NULL )
        {
            if( record[b] == 1 )       //借助哈希表找到第一个公共节点的指针
                return b;
            else
                b = b ->next;
        }
        return NULL;

    }
};

 

日积月累,与君共进,增增小结,未完待续。   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值