var findDuplicate = function(nums) {
nums.sort((a, b) => a - b);
for (let i = 1; i < nums.length; i++) {
const isPrevDuplicate = nums[i - 1] === nums[i]
if (isPrevDuplicate) return nums[i];
}
return -1;
}
var findDuplicate = function(nums) {
let [ left, right, duplicate ] = [ 1, (nums.length - 1), -1 ];
while (left <= right) {
const mid = (left + right) >> 1;
const count = getCount(mid, nums);
const isMidGreater = count <= mid
if (isMidGreater) left = mid + 1;
const isMidLess = mid < count
if (isMidLess) {
duplicate = mid;
right = mid - 1;
}
}
return duplicate;
}
const getCount = (mid, nums, count = 0) => {
for (const num of nums) {
const isMidGreater = num <= mid
if (isMidGreater) count++;
}
return count;
}
var findDuplicate = function(nums, duplicate = 0) {
const mostSignificantBit = calcMaxBit(nums);
for (let bit = 0; bit < mostSignificantBit; bit++) {
const [ baseCount, numsCount, mask ] = count(nums, bit);
const isMoreFrequentlySet = baseCount < numsCount
if (isMoreFrequentlySet) duplicate |= mask;
}
return duplicate;
}
const calcMaxBit = (nums, bits = 0) => {
let max = Math.max(0, ...nums);
while (max) {
max >>= 1;
bits++;
}
return bits;
}
const count = (nums, bit) => {
let [ baseCount, numsCount, mask ] = [ 0, 0, (1 << bit) ];
for (let i = 0; i < nums.length; i++) {
const isBaseBitSet = 0 < (i & mask);
if (isBaseBitSet) baseCount++;
const isNumBitSet = 0 < (nums[i] & mask);
if (isNumBitSet) numsCount++;
}
return [ baseCount, numsCount, mask ];
}
var findDuplicate = function(nums, curr = 0) {
const isBaseCase = curr === nums[curr]
if (isBaseCase) return curr;
const next = nums[curr];
nums[curr] = curr;
return findDuplicate(nums, next);
}
var findDuplicate = function(nums, seen = new Set()) {
for (const num of nums) {
if (seen.has(num)) return num;
seen.add(num);
}
return -1;
}
var findDuplicate = function(nums) {
cyclicSort(nums);
return search(nums);
}
const cyclicSort = (nums, index = 0) => {
const swap = (arr, a, b) => [arr[a], arr[b]] = [arr[b], arr[a]];
while (index < nums.length) {
const [ num, arrayIndex, arrayNum ] = [ nums[index], (nums[index] - 1), nums[(nums[index] - 1)] ];
const canSwap = !isSame(num, arrayNum);
if (canSwap) {
swap(nums, index, arrayIndex);
continue;
}
index++;
}
}
const isSame = (a, b) => a === b;
const search = (nums) => {
for (let index = 0; index < nums.length; index++) {
const [ num, arrayIndex ] = [ nums[index], (index + 1) ];
if (!isSame(num, arrayIndex)) return num;
}
return nums.length;
}
var findDuplicate = function(nums) {
const duplicate = negativeMarking(nums);
restoreToPositiveNumbers(nums);
return duplicate;
}
const negativeMarking = (nums) => {
for (let i = 0; i < nums.length; i++) {
const curr = Math.abs(nums[i]);
const isNegative = nums[curr] < 0;
if (isNegative) return curr;
nums[curr] *= -1;
}
return -1
}
const restoreToPositiveNumbers = (nums) => {
for (let i = 0; i < nums.length; i++) {
nums[i] = Math.abs(nums[i]);
}
}
var findDuplicate = function(nums, start = 0) {
const swap = (arr, a, b) => [arr[a], arr[b]] = [arr[b], arr[a]];
const isSame = () => nums[start] === nums[nums[start]];
while (!isSame()) {
swap(nums, start, nums[start]);
}
return nums[start];
}
var findDuplicate = function(nums) {
if (!nums.length) return -1
let [ slow, fast ] = moveFast(nums);
[ slow, fast ] = moveSlow(nums, slow, fast);
return slow;
};
const moveFast = (nums, start = 0) => {
let [ slow, fast ] = [ nums[start], nums[nums[start]] ];
const isSame = () => slow === fast;
while (!isSame()) {
slow = nums[slow];
fast = nums[nums[fast]];
}
fast = start;
return [ slow, fast ];
}
const moveSlow = (nums, slow, fast) => {
const isSame = () => slow === fast;
while (!isSame()) {
slow = nums[slow];
fast = nums[fast];
}
return [ slow, fast ];
}