1.解法与解析
1.1 注意事项
- circle里的元
素方向一致,“Furthermore, movements in a cycle must all follow a single direction.”
- 检验不是index0开头的路径就可以,需要检验所有index开头的路径
1.2 解
bool circularArrayLoop(int* nums, int numsSize){
for (int i = 0; i < numsSize; i++) {
nums[i] %= numsSize; //normalization
}
for (int i = 0; i < numsSize; i++) {
int direction = nums[i] > 0;
for (int j = i; nums[j] < numsSize && direction == nums[j] > 0;) {
int temp_j = j;
j = (j + numsSize + nums[j]) % numsSize; // j = j_next
if (nums[j] == numsSize + i) { //是否本轮走过
return true;
}
nums[temp_j] = numsSize + i; //标记脚印
}
}
return false;
}
1.3 解析
- 判断是否有circle,可以使用fast和slow双指针,也可以标记走过的脚印,考虑到“注意事项”中第二点,此处标记脚印时间复杂度会更少 link
- j = j_next 表达式为
j = (j + numsSize + nums[j] % numsSize) % numsSize;
- 考虑
j = (j + numsSize + nums[j] % numsSize) % numsSize;
与j = (j + numsSize + nums[j]) % numsSize;
的计算量,标准化(normalization)是需要的
- 长度为1的去除,一般可以用
j != j_next
,此处用到的是,nums[j] < numsSize
、(nums[j] == numsSize + i)的return
、nums[temp_j] = numsSize + i;
的结合,规避了长度为1的情况
2. 总结
1、不是o(1)extra对应的就是fast和slow
2、能不能改原数据不是定死的,需灵活变化
2.1、必要的预处理很重要,常见的预处理有:排序,标准化
3、空间复杂度的o(1)不是1一个变量的空间,指的是固定常量的空间
3.1、同上,时间复杂度o(n)不一定指的就是单个循环,是o(2n)、o(3n)的统称;
4、时间复杂度o(n²)和h循环嵌套循环不完全等价,里层循环与外面的循环互斥,也可认为o(n)
5、不要太拘泥于形式,leetcode上面的时间、内存判定也有误差,在答案相同时,不需要在0、4ms时间消耗上,0.1、0.2m空间消耗上做文章
project
3. Extra(吐槽篇)
- 本题不是考解法,更重要的考认真读题😂😂,举个栗子:为什么
{3,1,2}
可以?为什么{0,1,2}
不可以;为什么{1, 2, 3, 4, 5}
可以?为什么{-2, 1, -1, -2, -2}
不可以;