You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java方向网格循环查找:计算前置指令数与循环长度

你原来的方案仅能判断循环存在,核心问题是只标记了节点是否被访问过,没有记录每个节点第一次被访问时的步数,无法推导循环前长度和循环本身长度,以下是两种可行解法:

解法1:哈希表记录访问时序(最直观,推荐)

由于每个坐标点的下一跳是唯一的,我们只需要在遍历路径的过程中,用哈希表存储每个坐标(row, col)对应的首次访问步数即可,逻辑如下:

  • 每走到一个新坐标,先检查是否已经在哈希表中存在
  • 若不存在,将当前坐标和当前总步数存入哈希表,按照方向移动到下一个坐标,总步数+1
  • 若已存在,说明找到循环起点:
    • 循环前的指令步数 = 该坐标在哈希表中存储的首次访问步数
    • 循环本身的指令步数 = 当前总步数 - 该坐标的首次访问步数

对应Java实现参考:

// 起始位置按题目要求给定,示例为(0,0)
int curRow = 0, curCol = 0;
int totalStep = 0;
// 哈希表key存储坐标,格式为"行,列",value存储首次访问该坐标的步数
Map<String, Integer> visitedPos = new HashMap<>();

while (true) {
    String posKey = curRow + "," + curCol;
    // 命中已访问坐标,找到循环
    if (visitedPos.containsKey(posKey)) {
        int preCycleSteps = visitedPos.get(posKey);
        int cycleLength = totalStep - preCycleSteps;
        // 输出结果,也可根据需求返回
        System.out.println("循环前步数:" + preCycleSteps + ",循环长度:" + cycleLength);
        break;
    }
    // 记录当前坐标的首次访问步数
    visitedPos.put(posKey, totalStep);
    // 按方向移动
    char direction = grid.get(curRow).get(curCol);
    switch (direction) {
        case 'N': curRow--; break;
        case 'S': curRow++; break;
        case 'W': curCol--; break;
        case 'E': curCol++; break;
    }
    totalStep++;
}

该方法时间复杂度为O(nm),空间复杂度为O(nm),常规网格场景下性能足够,且不需要修改原网格数据。

解法2:快慢指针法(空间复杂度优化到O(1))

如果网格规模极大,要求不使用额外存储,可以用弗洛伊德循环查找算法(龟兔赛跑法)实现:

  • 第一步:慢指针每次走1步,快指针每次走2步,直到两个指针相遇,证明循环存在
  • 第二步:将慢指针放回起始位置,快慢指针每次都走1步,再次相遇的位置就是循环的起点,此时走的步数就是循环前的指令步数
  • 第三步:固定其中一个指针在循环起点,另一个指针每次走1步,直到回到起点,走的步数就是循环本身的指令步数

该方法不需要额外存储访问记录,空间复杂度为O(1),仅需要多轮遍历即可得到结果。

内容的提问来源于stack exchange,提问作者ParkerHarrelson123

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 09:09:05