剑指offer——两个链表的第一个公共结点C++

38 篇文章 0 订阅
25 篇文章 0 订阅

在这里插入图片描述
链表题一定要想到快慢指针
三种方法:
1.用一个map记录第一条链表每个结点是否出现,遍历第二条时判断即可。
2.我称之为相亲相爱法,因为两条链表的长度不确定,所以让两个指针分别走1+2两条链表的长度就可以了,这样走的就是相等了。两个结点相等时退出循环(这样就算两个结点都指向空结点也不会死循环)。当1为空,就让1指向链表2的头,2为空,就让2指向链表1的头。
3.算出两条链表的长度len1和len2,假设len1>len2,就让链表1的指针先走len1-len2步,然后再一起走就行了

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
public:
    ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
        if(pHead1 == NULL || pHead2 == NULL){
            return NULL;
        }
        //法一来个map记录出现过的结点,遍历第二条链表时判断是否出现过
        /*O(N),O(N)
        map<ListNode*,int> ma;
        while(pHead1 != NULL){
            ma[pHead1]++;
            pHead1 = pHead1->next;
        }
        while(pHead2 != NULL){
            if(ma[pHead2] != 0){
                return pHead2;
            }
            pHead2 = pHead2->next;
        }
        return NULL;*/
        
        //最好是O(1)的空间复杂度,链表就要想到快慢指针
        //两种快慢指针的思路1:相亲相爱
        /*ListNode* a = pHead1;
        ListNode* b = pHead2;
        while(a != b){
            //如果两个指针同时到达NULL,就把NULL看做公共节点
            //所以不能用a->next==null来判断,这样a和b永远不会变成NULL,如果没有交点就是死循环了
            a = a == NULL ? pHead2 : a->next;
            b = b == NULL ? pHead1 : b->next;
        }
        return a;*/
        
        //2:长的先走
        int len1 = 0, len2 = 0;
        ListNode* a = pHead1;
        ListNode* b = pHead2;
        while(a != NULL){
            len1++;
            a = a->next;
        }
        while(b != NULL){
            len2++;
            b = b->next;
        }
        if(len1 > len2){
            //第一条比较长,走len1-len2步
            while((len1 - len2) != 0){
                pHead1 = pHead1->next;
                len1--;
            }
        }
        else{
            while((len2-len1)!=0){
                pHead2 = pHead2->next;
                len2--;
            }
        }
        while(pHead1 != pHead2){
            pHead1 = pHead1->next;
            pHead2 = pHead2->next;
        }
        return pHead1;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值