Java中可用数组模拟链表并用快慢指针检测环:以next[i]表示节点i的后继索引,slow每次移1步、fast每次移2步,若相遇则有环,若越界则无环。
java 中无法直接用数组实现真正的环形链表,但可以用数组模拟链表结构,再应用快慢指针法检测环。核心在于:把数组当作“节点存储池”,用数组元素值表示“下一个节点的索引”,从而构建逻辑上的单向链表;再在此逻辑链表上运行 floyd 判圈算法。
用数组模拟链表结构
假设有一个 int[] next 数组,其中 next[i] 表示从节点 i 出发指向的下一个节点索引。例如:
- next = {1, 2, 3, 4, 2} 表示:0→1→2→3→4→2→3→4→…,存在环(2→3→4→2)
- 合法索引范围是 0 到 next.length - 1;若 next[i] 或 next[i] >= next.length,视为链表终止(无环出口)
快慢指针在数组上的实现逻辑
定义两个“游标”:slow(每次走 1 步)、fast(每次走 2 步),均从起始索引(如 0)出发:
- slow = next[slow]
- fast = next[next[fast]](需确保中间步不越界,否则提前判定无环)
- 若 slow == fast ≠ -1(且未越界),说明相遇 → 存在环
- 若任一指针越界(如 next[fast] 越界,或 next[next[fast]] 越界),则链表终结 → 无环
完整可运行示例代码
以下是一个健壮的检测方法,处理边界与异常:
public static boolean hasCycle(int[] next, int start) {
if (next == null || start < 0 || start >= next.length) return false;
<pre class="brush:php;toolbar:false;">int slow = start, fast = start;
while (true) {
// slow 走一步
slow = next[slow];
if (slow < 0 || slow >= next.length) return false; // 终止
// fast 走两步(分步检查)
int mid = next[fast];
if (mid < 0 || mid >= next.length) return false;
fast = next[mid];
if (fast < 0 || fast >= next.length) return false;
if (slow == fast) return true;
}}
立即学习“Java免费学习笔记(深入)”;
注意事项与常见陷阱
实际使用中需注意:
- 数组必须代表**确定的单向映射**,即每个位置最多一个出边(符合链表语义)
- 起始点不一定是 0 —— 若链表有多个入口(如森林),需对每个未访问起点单独检测
- 该方法只判环存在性,不找入环点;若需找环入口,可在相遇后重置 slow 到起点,再同步单步推进直至再次相遇
- 避免无限循环:务必在每次数组访问前校验索引有效性


















