leetcode
leetcode 2851 ~ 2900
消失的两个数字

消失的两个数字

难度:

标签:

题目描述

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的所有数字的理论和以及数组中的实际和?这样做的目的是什么?
计算从1到N的所有数字的理论和和数组中的实际和,目的是确定两个缺失数字的总和。这是因为从1到N的和是一个固定的数值,可以通过公式计算得出。而数组中的实际和是当前数组中所有数字的总和。两者的差值即为缺失的两个数字的和。这个差值是找出缺失数字的关键第一步。
🦆
如何保证用`missing_total // 2`作为界限可以有效地区分两个缺失的数字?是否存在特殊情况下这种方法会失效?
使用`missing_total // 2`作为界限来区分两个缺失数字基于一个假设:缺失的两个数字分别位于1到limit和limit+1到N的范围内。这个方法通常有效,因为即使两个缺失数字的和接近但不等于N,它们也会被分到两个不同的区间。然而,如果两个缺失的数字恰好相等并且等于`missing_total // 2`,这种方法可能会失效,因为这样的数字将不会被正确地区分到两个不同的区间。
🦆
在计算小于或等于`limit`的所有数字和时,如果数组中存在重复数字但仍然缺少两个数字,这种方法还适用吗?
这种方法假设数组中不存在重复数字,且确实缺少两个数字。如果数组中存在重复的数字,则计算的实际和不再只是简单地缺少两个数字的和,这可能导致计算错误。在存在重复数字的情况下,这种基于和的方法可能不再适用,需要采用其他方法(如位运算或哈希表)来正确识别缺失的数字。

相关问题