算法-单链表-判断链表是否有环,是否交叉,计算环长,计算入环节点

1.判断一个单链表是否存在环:

import java.util.*;

/*
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}*/
public class ChkLoop {
    public boolean chkLoop(ListNode head, int adjust) {
        if(head==null)
            return -1;
        //判断该链表是否存在环,让quick每次走两步,让slow每次走一步,若存在环,quick和slow必定会相遇
        //就和在操场跑道跑步一样,一个人慢,一个人块,快的总会追到慢的。
        ListNode quick=head;
        ListNode slow=head;
        while(quick!=null && quick.next!=null){
            quick=quick.next.next;
            slow=slow.next;
            if(quick==slow){
                return true;
            }
    	}
    }
}


2.判断一个链表是否存在环,存在的话,输出入环节点的值,否则输出-1:

import java.util.*;
/*
public class ListNode {
    int val;
    ListNode next = null;


    ListNode(int val) {
        this.val = val;
    }
}*/
public class ChkLoop {
    public int chkLoop(ListNode head, int adjust) {
        if(head==null)
            return -1;
        //判断该链表是否存在环
        ListNode quick=head;
        ListNode slow=head;
        while(quick!=null && quick.next!=null){
            quick=quick.next.next;
            slow=slow.next;
            if(quick==slow){
                break;
            }
        }
        //如果quick!=slow,则表明不存在环,返回-1
        if(quick!=slow)
            return -1;
        //否则,判断入环节点的位置
        else{
            /*
            由于quick走的速度是slow的两倍,所以上面判断链表是否存在的过程中quick走的路程是
            slow的两倍,因此他两的相交点到入环节点的距离等于链表头节点到入环节点的距离(2-1=1)
            */
            ListNode a=head;
            ListNode b=quick;//或者b=slow
            //从头结点和相交点分别一步一步的走,当两者相等时,则为入环节点。
            while(a!=b){
                a=a.next;
                b=b.next;
            }
            return a.val;
        }
    }
}


3.判断一个单链表是否存在环,存在环的话输出环的长度,不存在的话输出-1:

import java.util.*;

/*
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}*/
public class ChkLoop {
    public boolean chkLoop(ListNode head, int adjust) {
        if(head==null)
            return -1;
        //判断该链表是否存在环
        ListNode quick=head;
        ListNode slow=head;
        while(quick!=null && quick.next!=null){
            quick=quick.next.next;
            slow=slow.next;
            if(quick==slow){
                break;
            }
    	}
        if(quick!=slow){
            return -1;
        }
        //若存在环,计算环的长度,当quick和slow进入环中,他两就只能在换里面转悠了
        //由于quick速度是slow的两倍,所以当他两下一次相遇时,slow走了一圈,quick走了两圈
        //故可以用slow计数,当相遇时,slow走了多少步,环的大小就是多少。
        else{
            int result=0;
            do{
                result++;
                quick=quick.next.next;
                slow=slow.next;
            }while(quick!=slow);
            return result;
        }
    }
}
4.判断两条单链表是否相交(注意:这里可能是V字形相交,也可能是Y字形相交)

import java.util.*;

/*
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}*/
public class CheckIntersect {
    public boolean chkIntersect(ListNode headA, ListNode headB) {
        // write code here
        //获取headA的尾节点
        ListNode wearFlagA=headA;
        while(wearFlagA.next != null){
            wearFlagA=wearFlagA.next;
        }
        //获取headB的尾节点
        ListNode wearFlagB=headB;
        while(wearFlagB.next != null){
            wearFlagB=wearFlagB.next;
        }
        //若两个尾节点不相等,则不可能是V字形相交,只可能是Y字形相交或者不想交
        if(wearFlagA!=wearFlagB)
            return false;
        //判断是Y字形相交还是不想交
        //将其中的一条链表首尾相接
        wearFlagA.next=headA;
        //从另外一条链表头开始往下找,若出现环,则证明相交,若无环,则证明不想交
        ListNode quick=headB;
        ListNode slow=headB;
        while(quick!=null && quick.next!=null){
            quick=quick.next.next;
            slow=quick.next;
            if(quick==slow){
                break;
            }
        }
        if(quick!=slow)
        	return false;
        else
            return true;
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值