题解 | #两个链表的第一个公共结点#

两个链表的第一个公共结点

http://www.nowcoder.com/practice/6ab1d9a29e88450685099d45c9e31e46

第四题 第一种解法,算长度可以化简
/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
            val(x), next(NULL) {
    }
};*/
class Solution {
public:
    // 他给的示例有点奇怪
    // 后来我调试了才看懂的,他给的是三个链表。最后函数收到的是第一个和第三个拼起来的;第二个和第三个拼起来的
    ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
        // 先判断两个长度 长的先走几个 让她变成一样长
        // 因为 最后结果是公共的 也就是说明长度肯定是一样的
        int len1=0;
        int len2=0;
        // 保存头,不然就丢了
        ListNode* head1=pHead1;
        ListNode* head2=pHead2;
        while(pHead1!=NULL){
            len1++;
            pHead1=pHead1->next;
        }
        while(pHead2!=NULL){
            len2++;
            pHead2=pHead2->next;
        }
        
        // 第一个长 几个 就先往后走几步
        // 第二个长的话 就只会执行第二个while循环
        while(len1>len2)
        {
            head1=head1->next;
            len1--;
        }
        while(len2>len1)
        {
            head2=head2->next;
            len2--;
        }
        
        // 保存返回答案的头结点
        ListNode* ans=new ListNode(0);
        
        // 因为要求保存最长,每次都要判断后面是否相等,但是不可能每次都要更新节点
        // temp用来前面是否相等 相等的话,后面如果等,就不用赋值,不相等,就要赋值 并修改temp
        int temp=-1;
        // 现在一样长了,开始做最后的判断
        while(head1!=NULL)
        {
            if(head1->val==head2->val)
            {
                if (temp!=1){
                    ans->next=head1;
                    temp=1;
                }
            }
            else{
                temp=-1;
                ans->next=NULL;
            }
            head1=head1->next;
            head2=head2->next;
        }
        return ans->next;
    }
};

第二种 稍微优化了一点点
/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
            val(x), next(NULL) {
    }
};*/
class Solution {
public:
    // 他给的示例有点奇怪
    // 后来我调试了才看懂的,他给的是三个链表。最后函数收到的是第一个和第三个拼起来的;第二个和第三个拼起来的
    ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
        // 保存头,不然就丢了
        ListNode* head1=pHead1;
        ListNode* head2=pHead2;
        
        // 代码改进,不需要记录长度,一开始就往后走,总有一个先走完。
        // 对于没走完的,后面还剩几个,就代表长了几个
        while(pHead1!=NULL && pHead2!=NULL){
            pHead1=pHead1->next;
            pHead2=pHead2->next;
        }
        // 后面还剩的和它的开头一起开始走
        // 比如说 第一个长度为6,第二个长度为4
        // 那么,当上面那个循环做完后,第一个后面还剩两个就结束了
        // 此时,再扔到循环里面,让他的头和他一起走完两个,最后就是只剩四个了
        // 相比计算两个sum少掉几个循环
        // 时间复杂度都是O(n) 那不会变
        while(pHead1!=NULL){
            head1=head1->next;
            pHead1=pHead1->next;
        }
        while(pHead2!=NULL){
            head2=head2->next;
            pHead2=pHead2->next;
        }
        
        // 保存返回答案的头结点
        ListNode* ans=new ListNode(0);
        
        // 因为要求保存最长,每次都要判断后面是否相等,但是不可能每次都要更新节点
        // temp用来前面是否相等 相等的话,后面如果等,就不用赋值,不相等,就要赋值 并修改temp
        int temp=-1;
        // 现在一样长了,开始做最后的判断
        while(head1!=NULL)
        {
            // 和第一版基本一样 判断temp直接在if判断了,不用分开来写
            if(head1->val==head2->val && temp!=1)
            {
                ans->next=head1;
                temp=1;
            }
            else if(head1->val!=head2->val){
                temp=-1;
                ans->next=NULL;
            }
            head1=head1->next;
            head2=head2->next;
        }
        return ans->next;
    }
};
题解 文章被收录于专栏

一遍做剑指offer 一边保存做题步骤 并附带详细注释哦

全部评论

相关推荐

不愿透露姓名的神秘牛友
11-21 19:05
面试官_我太想进步了:混学生会的,难怪简历这么水
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务