博客
关于我
环形数组循环
阅读量:405 次
发布时间:2019-03-06

本文共 2039 字,大约阅读时间需要 6 分钟。

环形数组循环问题需要判断数组中是否存在符合条件的循环。循环的定义是从同一个起始点出发,经过若干步后回到起始点,且循环长度大于1,同时循环中的所有移动必须是同方向的。以下是详细的分析和解决方案。


问题分析

给定一个环形数组 nums,其中包含正整数和负整数。每个元素 k 表示移动的步数,正数表示向前移动,负数表示向后移动。我们需要检测是否存在一个循环,使得从某个起始点出发,经过若干步后回到起始点,且循环长度 > 1,同时所有移动方向一致。


解决思路

为了检测循环,我们可以使用快慢指针技术:

  • 定义函数 getNext:计算当前索引的下一个索引,确保环形处理。
  • 遍历数组:忽略值为0的元素,因为它们无法移动。
  • 使用快慢指针:慢指针一步步移动,快指针每次移动两步。如果找到同方向的循环且长度 > 1,返回 true
  • 剪枝处理:避免重复处理已检查过的索引。

  • 解决代码

    const circularArrayLoop = function(nums) {    const n = nums.length;    if (n === 0) return false;    const getNext = (x) => {        const next = (x + nums[x]) % n;        return next < 0 ? next + n : next;    };    for (let i = 0; i < n; i++) {        if (nums[i] === 0) continue;        let slow = i;        let fast = getNext(i);        while (true) {            // 检查当前元素和下一个元素的符号是否相同            if (nums[slow] * nums[fast] <= 0) break;            // 检查下一个元素和它的下一个元素的符号是否相同            if (nums[fast] * nums[getNext(fast)] <= 0) break;            // 如果慢指针和快指针相遇,判断是否形成循环            if (slow === fast) {                if (slow === getNext(slow)) {                    // 循环长度为1,不符合条件                    break;                } else {                    // 检查是否所有元素都在同一个循环中                    let tmp = slow;                    let prev = slow;                    let count = 1;                    while (tmp !== prev) {                        tmp = getNext(tmp);                        if (nums[tmp] * nums[prev] <= 0) break;                        prev = tmp;                        count++;                    }                    if (count > 1) return true;                }            }            slow = getNext(slow);            fast = getNext(getNext(fast));        }        // 剪枝处理,从i开始的所有元素置0        let tmp = i;        let val = nums[tmp];        while (val !== 0) {            nums[tmp] = 0;            tmp = getNext(tmp);            val = nums[tmp];        }    }    return false;};

    代码解释

  • getNext 函数:计算当前索引的下一个索引,使用模运算处理环形数组。
  • 遍历数组:对于每个元素,跳过值为0的情况。
  • 快慢指针:慢指针和快指针分别移动一步和两步,检查是否存在同方向的循环。
  • 剪枝处理:将已处理索引及其后续元素置0,避免重复处理。
  • 通过上述步骤,可以有效检测环形数组中是否存在符合条件的循环。

    转载地址:http://apckz.baihongyu.com/

    你可能感兴趣的文章
    NPOI将某个程序段耗时插入Excel
    查看>>
    NPOI格式设置
    查看>>
    NPOI设置单元格格式
    查看>>
    Npp删除选中行的Macro录制方式
    查看>>
    NR,NF,FNR
    查看>>
    nrf24l01+arduino
    查看>>
    nrf开发笔记一开发软件
    查看>>
    nrm —— 快速切换 NPM 源 (附带测速功能)
    查看>>
    nrm报错 [ERR_INVALID_ARG_TYPE]
    查看>>
    NS3 IP首部校验和
    查看>>
    NSDateFormatter的替代方法
    查看>>
    NSError 的使用方法
    查看>>
    NSGA-Ⅲ源代码
    查看>>
    nsis 安装脚本示例(转)
    查看>>
    NSJSON的用法(oc系统自带的解析方法)
    查看>>
    nslookup 的基本知识与命令详解
    查看>>
    NSOperation基本操作
    查看>>
    NSRange 范围
    查看>>
    NSSet集合 无序的 不能重复的
    查看>>
    NSURLSession下载和断点续传
    查看>>