单链表环相关问题

1、判断是否有环

https://leetcode-cn.com/problems/linked-list-cycle/

思路,快慢指针,快指针先于慢指针入环,然后相遇

public boolean hasCycle(ListNode head) {
         ListNode fast,slow;
       fast = slow = head;
       while (slow!=null && fast.next!=null){
           slow = slow.next;
           fast = fast.next.next;
           if(slow == null || fast == null) return false;
           if(slow == fast) return true;
       }
       return false;
    }

2、获取环的入口节点

https://leetcode-cn.com/problems/linked-list-cycle-ii/

推导公式:

2*S = s+n*r
s = n*r
a + x = s = n*r
a + x = (n-1)*r + r = (n-1)*r + (L-a)
a= (n-1)*r + (L-a -x)

代码:

public static ListNode detectCycle(ListNode head) {
        ListNode fast, slow;
        fast = slow = head;
        while (slow!=null && fast.next!=null){
            slow = slow.next;
            fast = fast.next.next;
            if(slow == null || fast == null) return null;
            if(slow == fast) break;
        }
        if(slow == null || fast.next == null) return null;
        while (head != slow){
            head = head.next;
            slow = slow.next;
        }
        return head;
    }

3.得到环的节点数

    public int getCircleSize(ListNode head){
        ListNode fast,slow;
        fast = slow = head;
        while (slow!=null && fast.next!=null){
            slow = slow.next;
            fast = fast.next.next;
            if(slow ==null || fast == null) return 0;
            if(slow == fast) break;
        }
        if(slow == null || fast.next == null) return 0;
        ListNode temp = slow.next;
        int count = 1;
        while (temp != slow){
            temp = temp.next;
            count++;
        }
        return count;
    }

4 得到单链表长度

public int getLinkListSize(ListNode head){
        ListNode fast,slow;
        fast = slow = head;
        int count = 0;
        boolean isCircle = false;
        while (slow!=null && fast.next!=null){
            count++;
            slow = slow.next;
            fast = fast.next.next;
            if(slow ==null || fast == null){
                isCircle = false;
                break;
            }
            if(slow == fast) {
                isCircle = true;
                break;
            }
        }
        if(isCircle){ //如果是环,链表节点个数 应该是 到环入口节点数 + 环的节点数
            ListNode p = head;
            ListNode q= slow;
            int startCount = 0; //链表起点到 环入口节点数(不包含环入口节点)
            while (p != q){
                startCount++;
                p = p.next;
                q = q.next;

            }
            ListNode temp = slow.next;
            int circleCount = 1; //环节点数
            while (temp != slow){
                temp = temp.next;
                circleCount++;
            }
            return startCount + circleCount;
        }else{
            while (slow!=null){
                count++;
                slow = slow.next;
            }
            return count;
        }
    }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值