题目描述
给定一个数组,包含从 1 到 N 所有的整数,但其中缺了两个数字。你能在 O(N) 时间内只用 O(1) 的空间找到它们吗?
以任意顺序返回这两个数字均可。
示例 1:
示例 2:
提示:
来源:力扣(LeetCode)
题解
数学
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| public int[] missingTwo(int[] nums) { int n = nums.length + 2; int sum = n * (n + 1) >> 1; long squareSum = 0; for (int i = 0; i <= n; i++) { if (i < nums.length) { sum -= nums[i]; squareSum -= nums[i] * nums[i]; } squareSum += i * i; } long diff = (long) Math.sqrt(squareSum * 2 - sum * sum); return new int[]{(int) (sum - diff) / 2, (int) (sum + diff) / 2}; }
|
数学求和
1 2 3 4 5 6 7 8 9 10 11 12
| public int[] missingTwo(int[] nums) { int n = nums.length + 2; int total = (1 + n) * n >> 1; for (int num : nums) total -= num; int avg = total >> 1; int subTotal = (1 + avg) * avg >> 1; for (int num : nums) { if (num <= avg) subTotal -= num; } return new int[]{subTotal, total - subTotal}; }
|
位运算
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public int[] missingTwo(int[] nums) { int n = nums.length + 2; int xorSum = 0; for (int num : nums) xorSum ^= num; for (int i = 1; i <= n; i++) xorSum ^= i; int one = 0; int lowest = (xorSum == Integer.MIN_VALUE) ? xorSum : xorSum & -xorSum; for (int num : nums) if ((num & lowest) == 0) one ^= num; for (int i = 1; i <= n; i++) if ((i & lowest) == 0) one ^= i; return new int[]{one, xorSum ^ one}; }
|
标记
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public int[] missingTwo(int[] nums) { int[] temp = new int[]{1, 1}; int n = nums.length; for (int i = 0; i < n; i++) { int index = Math.abs(nums[i]) - 1; if (index < n) nums[index] *= -1; else temp[index - n] = -1; } int[] ans = new int[2]; int index = 0; for (int i = 0; i < n; i++) if (nums[i] > 0) ans[index++] = i + 1; for (int i = 0; i < 2; i++) if (temp[i] > 0) ans[index++] = n + i + 1; return ans; }
|
参考资料
__END__