题目
- 对于有序数组,通过二分查找,如果当前位置和它相邻位置相等则返回,如果不相等,当前位置的值能和索引相同(索引和值都从 0 开始),那说明左边没有重复值,如果小于索引值,那说明左边有重复值,进行二分
- 对于无需数组,那么通过值跳往对应下标,循环这样的方式一定存在环,结论:通过快慢指针相遇后,快指针回到原点每次走1步,再次和慢指针相遇的点就是环的起始点
// 有序数组情况
function process(arr) {
let left = 0,
right = arr.length - 1;
while (left < right) {
let mid = left + ((right - left) >> 1);
if (
(mid + 1 < arr.length && arr[mid] === arr[mid + 1]) ||
(m - 1 >= 0 && arr[mid - 1] === arr[mid])
) {
return arr[mid];
// 说明左边没用重复数字
} else if (arr[mid] === mid) {
left = mid + 1;
} else {
right = mid - 1;
}
}
}
// 无序数组情况
function process(arr) {
let slow = arr[0];
// 快指针一次跳两步
let fast = arr[arr[0]];
while (slow !== fast) {
slow = arr[slow];
fast = arr[arr[fast]];
}
// 结论:当相遇后,快指针从起始位置走1步,再次和慢指针相遇时的位置就是环的起始位置
fast = 0;
while (slow !== fast) {
slow = arr[slow];
fast = arr[fast];
}
return slow;
}