您的位置:首页 > 其它

牛客网算法学习记录-链表2

2016-05-25 22:14 302 查看
如何判断一个单链表是否有环?有环的话返回进入环的第一个节点的值,无环的话返回-1。如果链表的长度为N,请做到时间复杂度O(N),额外空间复杂度O(1)。

给定一个单链表的头结点head(注意另一个参数adjust为加密后的数据调整参数,方便数据设置,与本题求解无关),请返回所求值。

方法:设置一个快步指针和一个慢步指针,快步指针和慢步指针同时向前,如果不存在环,那么快步指针必定会变为NULL 或者它的next为NULL;

否则有环,当快步结点和慢步结点相遇,重置快步结点,步长变为一步,然后执行,当快步结点与慢步结点相遇时就是环的入口结点。(我不会证明)

/*

struct ListNode {

    int val;

    struct ListNode *next;

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

};*/

class ChkLoop {

public:

    int chkLoop(ListNode* head, int adjust) {

        // write code here

      ListNode* slowStep = head;

        ListNode* fastStep = head;

        while(fastStep!=NULL&&fastStep->next!=NULL){

            slowStep = slowStep->next;

            fastStep = fastStep->next->next;

            if(slowStep == fastStep){

                break;

            }

        }

        if(fastStep==NULL ||fastStep->next == NULL){

            return -1;

        }

        fastStep = head;

        while(fastStep != slowStep){

            

            fastStep = fastStep->next;

            slowStep = slowStep->next;

       

            

        }

        

        return fastStep->val;

    }

};

现在有两个无环单链表,若两个链表的长度分别为m和n,请设计一个时间复杂度为O(n + m),额外空间复杂度为O(1)的算法,判断这两个链表是否相交。

给定两个链表的头结点headA和headB,请返回一个bool值,代表这两个链表是否相交。保证两个链表长度小于等于500。

相交的意思是从某一结点开始后面的结点都相同。

所以对于长的链表需要先向后运行一段距离,直到两个链表的剩余段相同时才进行比较,如果中间有某个结点相同则返回True

/*

struct ListNode {

    int val;

    struct ListNode *next;

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

};*/

class CheckIntersect {

public:

    bool chkIntersect(ListNode* headA, ListNode* headB) {

        // write code here

        int dv = 0;

        int lena = 0,lenb = 0;

        ListNode *head;

        head = headA;

        while(head!=NULL){

            lena++;

            head = head->next;

        }

        head = headB;

        while(head!=NULL){

            lenb++;

            head = head->next;

        }

        

        if(lena>=lenb){

            dv = lena - lenb;

            while(dv>0){

                headA = headA->next;

                dv--;

            }

            while(headA!=NULL&&headB!=NULL){

                

                if(headA == headB){

                    return true;

                }

                headA = headA ->next;

                headB = headB ->next;

                

            }

            return false;

        }

        else{

            dv = lenb - lena;

            while(dv>0){

                headB = headB->next;

                dv--;

            }

            while(headB!=NULL&&headA!=NULL){

                if(headA == headB){

                    return true;

                }

                headA = headA ->next;

                headB = headB ->next;

            }

            return false;

        }

        

    }

};

5.14

如何判断两个有环单链表是否相交?相交的话返回第一个相交的节点,不想交的话返回空。如果两个链表长度分别为N和M,请做到时间复杂度O(N+M),额外空间复杂度O(1)。

给定两个链表的头结点head1和head2(注意,另外两个参数adjust0和adjust1用于调整数据,与本题求解无关)。请返回一个bool值代表它们是否相交。

运行超时,但是没找到问题。

思路:先判断环是否有相交,再判断链是否相交,但是这个思路有问题,因为如果链有相交则环必定相交,所以只需要判断环是否相交。

/*

struct ListNode {

    int val;

    struct ListNode *next;

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

};*/

class ChkIntersection {

public:

    bool chkInter(ListNode* head1, ListNode* head2, int adjust0, int adjust1) {

        // write code here

        ListNode* entryNode1= getNode(head1);

        ListNode* entryNode2= getNode(head2);

        ListNode* saveEntry1 = entryNode1;

        ListNode* saveEntry2 = entryNode2;

        if(entryNode1 == entryNode2)

            return true;

        entryNode1 = entryNode1 ->next;

       

        while(entryNode1 != saveEntry1){

            if(entryNode1 == entryNode2){

                return true;

            }

            entryNode1 = entryNode1->next;   

        }

        int lena=0,lenb=0;

        ListNode *tHead1 = head1;

        ListNode *tHead2 = head2;

        while(tHead1!=saveEntry1){

            lena++;

            tHead1 = tHead1->next;

        }

        

        while(tHead2!=saveEntry2){

            lenb++;

            tHead2 = tHead2->next;

        }

   

        tHead1 = head1;

        tHead2 = head2;

        if(lena >= lenb){

            

            int dv = lena-lenb;

            while(dv>0){

                tHead1 = tHead1->next;

                dv--;

            }

            while(tHead1!=saveEntry1){

                if(tHead1 == tHead2){

                    return true;

                }

                tHead1 = tHead1->next;

                tHead2 = tHead2->next;

            }

            if(tHead1 == tHead2){

                return true;

            }else{

                return false;

            }

            

        }

        else{

            int dv = lenb - lena ;

            while(dv>0){

                tHead2 = tHead2->next;

                dv--;

            }

            while(tHead2!=saveEntry2){

                if(tHead2 == tHead1){

                    return true;

                }

                tHead2 = tHead2->next;

                tHead1 = tHead1->next;

            }

            if(tHead1 == tHead2){

                return true;

            }

            else{

                return false;

            }

        }

        

    }

    

    ListNode* getNode(ListNode *head){

        

        ListNode *fastStep = head;

        ListNode *slowStep = head;

        while(fastStep != slowStep){

            slowStep = slowStep ->next;

            fastStep = fastStep ->next->next;

        }

        fastStep = head;

        while(fastStep !=slowStep){

            fastStep = fastStep->next;

            slowStep = slowStep->next;

        }

        

        return fastStep;

    }

};

别人家的代码:

给定两个单链表的头节点head1和head2,如何判断两个链表是否相交?相交的话返回true,不想交的话返回false。

给定两个链表的头结点head1和head2(注意,另外两个参数adjust0和adjust1用于调整数据,与本题求解无关)。请返回一个bool值代表它们是否相交。

是一个综合题,代码居然一次过了=。=~

思路如函数名

/*

struct ListNode {

    int val;

    struct ListNode *next;

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

};*/

class ChkIntersection {

public:

    bool chkInter(ListNode* head1, ListNode* head2, int adjust0, int adjust1) {

        // write code here

        ListNode *entryNode1 = hasCircle(head1);

        ListNode *entryNode2 = hasCircle(head2);

        if(entryNode1==NULL &&entryNode2 != NULL||

          entryNode1 != NULL &&entryNode2 == NULL){

            return false;

        }

        if(entryNode1 == NULL &&entryNode2 ==NULL){

            return sameInLine(head1,head2);

        }

        else{

            

            return sameInCircle(entryNode1,entryNode2);

        }

    }

    

    

    ListNode*  hasCircle(ListNode*head){

        

        ListNode * fastStep = head;

        ListNode * slowStep = head;

        while(fastStep !=NULL && fastStep ->next !=NULL){

            fastStep = fastStep ->next->next;

            slowStep = slowStep ->next;

          if(slowStep == fastStep){

                break;

            }

        }

        if(fastStep == slowStep){

            while(head!=slowStep){

                head = head->next;

                slowStep = slowStep ->next;

            }

            return slowStep;

        }

        else{

            return NULL;

        }

    }

    

    bool sameInCircle(ListNode*head1,ListNode*head2){

        

        ListNode *temp = head1;

        if(head1 == head2){

            return true;

        }

        else{

            head1 = head1->next;

            while(temp!=head1){

                if(head1 == head2){

                    return true;

                }

                head1 = head1->next;

            }

            return false;

        }

        

    }

    

    bool sameInLine(ListNode*head1,ListNode* head2){

        

        int dv=0;

        int lena = 0,lenb = 0;

        ListNode * tHead1 =head1;

        ListNode * tHead2= head2;

        while(tHead1 !=NULL){

            lena++;

            tHead1 = tHead1->next;

        }

        while(tHead2 !=NULL){

            lenb++;

            tHead2 = tHead2 ->next;

        }

        if(lena>=lenb){

            dv = lena - lenb;

            while(dv>0){

                tHead1 = tHead1->next;

                dv--;

            }

            while(tHead1!=NULL){

                if(tHead1 == tHead2){

                    return true;

                }

                tHead1 = tHead1->next;

                tHead2 = tHead2->next;

            }

            return false;

        }

        else{

            dv = lenb - lena;

            while(dv>0){

                tHead2 = tHead2 ->next;

                dv--;

            }

            while(tHead2!=NULL){

                if(tHead1 == tHead2){

                    return true;

                }

                tHead1 =tHead1 ->next;

                tHead2 = tHead2 ->next;

            }

            return false;

        }

    }

};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: