题意整理
- 给定一个环形数组,开始的时候,牛牛在起始位置。
- 每经过1分钟,环形数组中对应元素减去1,并且牛牛会沿着环形数组不断后移。
- 如果牛牛所在位置,元素值小于等于0,则返回对应位置下标。
方法一(模拟)
1.解题思路
- 用一个变量记录排队时间。
- 通过循环,模拟遍历环形数组,没执行一次,排队时间加一,如果对应下标元素值减去排队时间小于等于0,说明可以进入对应的门,直接返回。
测试数据较大的时候,运行超时。
2.代码实现
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 返回牛牛最终是从第几个门进入食堂吃饭的
* @param n int整型 代表门的数量
* @param a int整型一维数组 代表每个门外等待的人数
* @return int整型
*/
public int nowcoderQueue (int n, int[] a) {
//记录排队时间
int time=0;
for(int i=0;i<n;i=(i+1)%n){
//如果某个门排队人数小于等于0,说明可以进入,直接返回对应门的编号
if(a[i]-time<=0){
return i+1;
}
time++;
}
return -1;
}
} 3.复杂度分析
- 时间复杂度:假设数组中最小值为min,最多需要循环
次,所以时间复杂度为
。
- 空间复杂度:需要额外常数级别的空间,所以空间复杂度为
。
方法二(预处理+模拟)
1.解题思路
简单分析:
由于每经过一圈,如果还不能进入到对应的门,牛牛都会回到起始位置。所以我们可以预先计算出最小值,如果最小值大于n,说明牛牛仍然会回到起始位置,没回到起始位置一次,数组中所有元素就要减去相应的排队时间n,所以直接减去n的倍数,直到最小值小于等于n。
基本步骤:
- 计算数组最小值。
- 对数组进行预处理,如果最小值大于n,所有元素减去n的倍数,直到最小值小于等于n。
- 按方法一的方式进行循环。
动图展示:
2.代码实现
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 返回牛牛最终是从第几个门进入食堂吃饭的
* @param n int整型 代表门的数量
* @param a int整型一维数组 代表每个门外等待的人数
* @return int整型
*/
public int nowcoderQueue (int n, int[] a) {
//计算最小值
int min=Integer.MAX_VALUE;
for(int i=0;i<n;i++){
min=Math.min(min,a[i]);
}
//如果最小值大于n,进行预处理
if(min>n){
int d=min/n*n;
//将所有数减去n的倍数,直到最小值小于n
for(int i=0;i<n;i++){
a[i]-=d;
}
}
//记录排队时间
int time=0;
for(int i=0;i<n;i=(i+1)%n){
//如果某个门排队人数小于等于0,说明可以进入,直接返回对应门的编号
if(a[i]-time<=0){
return i+1;
}
time++;
}
return -1;
}
} 3.复杂度分析
- 时间复杂度:假设数组中最小值为min,预处理之后,最多需要循环
次,所以时间复杂度为
。
- 空间复杂度:需要额外常数级别的空间,所以空间复杂度为
。

京公网安备 11010502036488号