面试题 17.19. 消失的两个数字[数学]

思路

缺少一个数字时,可以利用1-N的和减去数组中元素之和得到缺少的那个数字。
在这个基础上进行扩展,缺少两个数字时,假设缺少的数字为 a , b a,b a,b 0 < a < b 0<a<b 0<a<b,如果能找到一个关于 a , b a,b a,b的二元方程组,就可以通过方程组求解的方法来得到它们的值。
可以额外利用1-N平方和的方法得到一个 a 2 , b 2 a^2,b^2 a2,b2的公式,由数学知识我们可知:
1 + 2 + . . . + N = ( 1 + N ) N 2 1 2 + 2 2 + . . . + N 2 = N ( N + 1 ) ( 2 N + 1 ) 6 1+2+...+N = \frac{(1+N)N}{2} \\ 1^2+2^2+...+N^2 = \frac{N(N+1)(2N+1)}{6} 1+2+...+N=2(1+N)N12+22+...+N2=6N(N+1)(2N+1)

可以得到两个方程:
a + b = x a 2 + b 2 = y a+b = x \\ a^2 + b^2 = y a+b=xa2+b2=y
通过这两个方程可以得到:
2 a b = x 2 − y ( a − b ) 2 = 2 y − x 2 2ab = x^2 - y \\ (a-b)^2 = 2y - x^2 2ab=x2y(ab)2=2yx2
由假设有: 0 < a < b 0<a<b 0<a<b,所以:
a − b = − 2 y − x 2 a-b = -\sqrt{2y-x^2} ab=2yx2
解出 a , b a,b a,b:
a = x − 2 y − x 2 2 b = x + 2 y − x 2 2 a = \frac{x-\sqrt{2y-x^2}}{2} \\ b = \frac{x+\sqrt{2y-x^2}}{2} a=2x2yx2 b=2x+2yx2

还需要注意的一点是,因为平方和公式的次数为三次方,且N <= 30000 N 3 ≤ 2.7 × 1 0 13 N^3 \le 2.7 \times 10^{13} N32.7×1013,会爆int,需要使用long类型来存储

代码如下:

class Solution {
    public int[] missingTwo(int[] nums) {
        int n = nums.length + 2;
        //设缺少的两个数为a,b
        // a+b = x
        long x = n*(1+n)/2 - Arrays.stream(nums).mapToLong(a->a).sum();
        // a^2 + b^2 = y
        long y = n*(1+n)*(1 + 2L *n)/6 - Arrays.stream(nums).mapToLong(a -> (long) a * a).sum();

//         2ab = x^2 - y
//         (a-b) ^ 2 = 2y-x^2
//         假设 a < b 则有 a-b = -√(2y-x^2)
//         a = [x-√(2y-x^2)]/2
//         b = [x+√(2y-x^2)]/2

        long sqrt = (long) Math.sqrt(2 * y - x * x);
        return new int[]{(int) ((x - sqrt)/2), (int) ((x + sqrt)/2)};
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值