zoukankan      html  css  js  c++  java
  • (剑指Offer)面试题37:两个链表的第一个公共结点

    题目:

    输入两个链表,找出它们的第一个公共结点。

    链表结点的定义如下:

    struct ListNode{
        int val;
        ListNode* next;
        ListNode(int x):val(x),next(NULL){};
    };
    

    思路:

    1、暴力法

    遍历第一个链表,每遍历到一个结点,在第二个链表中顺序遍历,如果在第二个链表上有一个结点和该结点一样,说明两个链表在这个结点上重合,也就是第一个公共结点。

    时间复杂度:O(mn)

    2、堆栈法

    如果两个链表存在公共结点,那么从第一个公共结点到链尾,所有结点都是重合的,如果我们从两个链表的尾部开始往前比较,最后一个相同的结点就是第一个公共结点。

    但单链表只有后继指针,不能往回移动,我们可以很快想到了栈,将两个链表的结点分别放入两个栈里,这样两个尾指针都在栈顶,接着下就比较栈顶指针是否相同,如果是,则把栈顶弹出,继续比较下一个栈顶,直至找到最后一个相同的结点。

    时间复杂度:O(m+n),空间复杂度:O(m+n)

    3、两个指针

    首先分别遍历两个链表A,B,得到各自的长度如lenA,lenB,假设lenA>lenB,然后让A指针先走lenA-lenB步,接着两个指针一块走,直至相遇即找到第一个公共结点。

    时间复杂度:O(m+n)

    代码:

    这里只实现方法3

    struct ListNode{
        int val;
        ListNode* next;
        ListNode(int x):val(x),next(NULL){};
    };
    
    unsigned int GetListLength(ListNode* pHead){
        unsigned int len=0;
        while(pHead!=NULL){
            len++;
            pHead=pHead->next;
        }
        return len;
    }
    
    ListNode* FindFirstCommonNode(ListNode* pHead1,ListNode* pHead2){
        unsigned int len1=GetListLength(pHead1);
        unsigned int len2=GetListLength(pHead2);
        ListNode* pLong=pHead1;
        ListNode* pShort=pHead2;
        unsigned lenDiff=len1-len2;
        if(len1<len2){
            pLong=pHead2;
            pShort=pHead1;
            lenDiff=len2-len1;
        }
    
        for(unsigned int i=0;i<lenDiff;i++)
            pLong=pLong->next;
    
        while(pShort!=NULL && pLong!=NULL && pShort!=pLong){
            pShort=pShort->next;
            pLong=pLong->next;
        }
    
        ListNode* pFirstCommonNode=pLong;
    
        return pFirstCommonNode;
    }
    

    在线测试OJ:

    http://www.nowcoder.com/books/coding-interviews/6ab1d9a29e88450685099d45c9e31e46?rp=2

    AC代码:

    /*
    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=GetListLength(pHead1);
            int len2=GetListLength(pHead2);
            ListNode* pLong=pHead1;
            ListNode* pShort=pHead2;
            int lenDiff=len1-len2;
            if(len1<len2){
                pLong=pHead2;
                pShort=pHead1;
                lenDiff=len2-len1;
            }
            
            for(int i=0;i<lenDiff;i++)
                pLong=pLong->next;
            
            while(pLong!=NULL && pShort!=NULL && pLong!=pShort){
                pLong=pLong->next;
                pShort=pShort->next;
            }
            
            ListNode* pFirstCommonNode=pLong;
            return pFirstCommonNode;
        }
        
        unsigned int GetListLength(ListNode* pHead){
            unsigned int len=0;
            while(pHead!=NULL){
                ++len;
                pHead=pHead->next;
            }
            return len;
        }
    };
    

      

  • 相关阅读:
    AFNetworking 3.0中调用[AFHTTPSessionManager manager]方法导致内存泄漏的解决办法
    UITableView自动计算cell高度并缓存
    iOS 10 应用内跳转到系统设置
    iOS 系统通知
    UITableViewDataSource TableView數據源協議
    HADOOP操作权限问题
    Echarts简单图表
    hadoop常见错误解决方法
    sqoop安装与简单实用
    hive的内置函数和自定义函数
  • 原文地址:https://www.cnblogs.com/AndyJee/p/4677891.html
Copyright © 2011-2022 走看看