成君:秒懂单链表寻找环入口

单链表寻找环入口问题

一、构造链表

public class ListNode {
    int val;
    ListNode next;
}

二、3个步骤

1. 判断是否存在环:快慢指针法

    /**
     * 判断是否有环
     * @return ListNode 相遇结点
     */
	public ListNode hasLoop(ListNode pHead) {
	    if (pHead == null || pHead.next == null || pHead.next.next == null) {
	        return null;
	    }
	    ListNode slow = pHead.next;// 慢指针 1 步
	    ListNode fast = pHead.next.next;// 快指针
	    while(fast != null) {
	        if(slow.equals(fast)) {
	            return slow;
	        }
	        slow = slow.next;// 慢指针
	        fast = fast.next;
	        if(fast != null) {
	            fast = fast.next;// 快指针 2 步
	        }
	    }
	    return null;
	}

2. 获取环的长度

	/** 
	 * 获取环的长度
	 */
	public int getLoopLength(ListNode node) {
		if (node == null) {return 0;}
	    ListNode temp = node.next;
	    int length = 1;
	    while(temp != node) {
	        length++;
	        temp = temp.next;
	    }
	    return length;
	}

3. 获取环入口:假设无环,双指针法获取倒数第 length 个结点

	/**
	 * 获取入口结点
	 */
	public ListNode getEntryNode(ListNode pHead, int length) {
		if (length == 0) {return null;}
        ListNode a = pHead;
        ListNode b = pHead;
        while (length-- > 0) {
            a = a.next;
        }
        while (a != b) { // 相遇时便是链尾,即入口
            a = a.next;
            b = b.next;
        }
        return a;
    }

测试

	public void test(ListNode pHead) {
		ListNode node = getEntryNode(getLoopLength(hasLoop(pHead)));
	}

三、总结

双指针可以解决大部分链表问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值