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

136 阅读1分钟

难度:困难

方法:数学

题目描述

给定一个数组,包含从 1 到 N 所有的整数,但其中缺了两个数字。你能在 O(N) 时间内只用 O(1) 的空间找到它们吗?

以任意顺序返回这两个数字均可。

示例

输入: [1]
输出: [2,3]

设该两个整数是a,bsum为[1,N]的整数和,subsum为给定数组的和,故有

  • a+b=sum-subsum

提示一

  • 将[1,N]所有数取乘积,subMuti为给定数组的乘积,有N!=a * b * subMuti

但是此时存在问题,N!太大了,已经超出了计算机的最大数存储范围

提示二

平方和是否有用?

  • [1,N]每个数取平方和,有squareNum=i=1N(i2)squareNum=\sum_{i=1}^{N}(i^2)
  • 同理,subSquareNum=i=0n1(nums[i]2)subSquareNum=\sum_{i=0}^{n-1}(nums[i]^2)
  • squareNumsubSquareNum=a2+b2squareNum-subSquareNum=a^2+b^2

l提示三

连立提示一和提示二

(a+b)2a2b2=2ab(a+b)^2-a^2-b^2=2ab,这不就得到ab了嘛

有公式

{ab=?a+b=??\left\{ \begin{array}{c} ab=? \\ a+b=?? \end{array} \right.

解出a、b

class Solution {
public:
    vector<int> missingTwo(vector<int>& nums) {
        int N=nums.size()+2;
        int n=nums.size();
        long long sum=0,sqir_2=0;
        for(int i=1;i<=N;i++){
            sum+=i;sqir_2+=i*i;
        }
        for(int i=0;i<n;i++)sum-=nums[i],sqir_2-=nums[i]*nums[i];
        int ab=(sum*sum-sqir_2)/2;
        vector<int>ans;
        for(int i=1;i<=N;i++){
            int b=sum-i;
            if(i*b==ab){
                ans.push_back(i);
                ans.push_back(b);
                break;
            }
        }
        return ans;
    }
};