消失的两个数字
难度:
标签:
题目描述
You are given an array with all the numbers from 1 to N appearing exactly once, except for two number that is missing. How can you find the missing number in O(N) time and 0(1) space?
You can return the missing numbers in any order.
Example 1:
Input: [1]
Output: [2,3]
Example 2:
Input: [2,3]
Output: [1,4]
Note:
nums.length <= 30000
代码结果
运行时间: 33 ms, 内存: 20.0 MB
// 思路:
// 1. 使用Stream计算实际总和和平方和。
// 2. 使用相同的公式计算期望的总和和平方和。
// 3. 使用公式求解出两个缺失数字。
import java.util.stream.IntStream;
public class FindMissingNumbersStream {
public static int[] findMissingNumbers(int[] nums) {
int n = nums.length + 2;
int actualSum = IntStream.of(nums).sum();
int actualSquareSum = IntStream.of(nums).map(x -> x * x).sum();
int expectedSum = n * (n + 1) / 2;
int expectedSquareSum = n * (n + 1) * (2 * n + 1) / 6;
int sumDiff = expectedSum - actualSum;
int squareSumDiff = expectedSquareSum - actualSquareSum;
int sumXY = (sumDiff * sumDiff - squareSumDiff) / 2;
int x = (sumDiff + (int) Math.sqrt(sumDiff * sumDiff - 4 * sumXY)) / 2;
int y = sumDiff - x;
return new int[]{x, y};
}
public static void main(String[] args) {
int[] nums1 = {1};
int[] nums2 = {2, 3};
System.out.println(Arrays.toString(findMissingNumbers(nums1))); // 输出: [2, 3]
System.out.println(Arrays.toString(findMissingNumbers(nums2))); // 输出: [1, 4]
}
}
解释
方法:
该题解采用了数学方法来找出缺失的两个数字。首先,计算从1到N的所有数字的理论和,然后从中减去数组中的实际和,得到两个缺失数字的总和。接下来,以这个总和的一半作为界限,将小于或等于这个界限的所有数字的和计算出来。这样可以找出小于或等于界限的那个缺失数字,进而通过总和减去这个数字得到第二个缺失数字。
时间复杂度:
O(n)
空间复杂度:
O(1)
代码细节讲解
🦆
为什么要首先计算从1到N的所有数字的理论和以及数组中的实际和?这样做的目的是什么?
▷🦆
如何保证用`missing_total // 2`作为界限可以有效地区分两个缺失的数字?是否存在特殊情况下这种方法会失效?
▷🦆
在计算小于或等于`limit`的所有数字和时,如果数组中存在重复数字但仍然缺少两个数字,这种方法还适用吗?
▷