问题描述

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

解题算法

法一:位运算

class Solution {
public://数组完全可能是乱序vector<int> missingTwo(vector<int>& nums) {vector<int> res;//法一:异或法  想办法将两个数分开,有点类似一sigleNumber的想法,有两个数落单;分出两个数组来异或int N = nums.size()+2;int tdiff = 0;for(int i=1;i<=N;i++){tdiff ^= i;}for(int i=0;i<nums.size();i++){tdiff ^= nums[i];}//diff此时是两个数的异或值,两个数不想等,利用mask标志分开两个数。 int mask = 1;while(!(mask & tdiff)){mask = mask << 1;}//mask现在就是第一个不同的xxxx1xxxx//两部分数用mask分开int one = 0;for(int i=0;i<nums.size();i++){if(mask & nums[i]) one ^= nums[i];}for(int i=1;i<=N;i++){if(mask & i) one ^= i;}res.push_back(one);res.push_back(one^tdiff);return res;}
};

法二:分组求和

class Solution {
public:vector<int> missingTwo(vector<int>& nums) {vector<int> res;//法二 分组求和int N = nums.size()+2;int sumN = 0,sumNum = 0,sumNumLess=0,sumNLess=0;for(auto num : nums)sumNum += num;for(int i=1;i<=N;i++)sumN += i;//diff是两个数的和int sumTwo = sumN - sumNum;//求两个数和的一半,那么两个缺失得数一个大于diff,一个小于diff。int diff = (sumTwo)/2;//针对 N 和sum两个数组,小于等diff的分别分为一组;大于diff的分别分为一组;那么两个组的差值即为缺失的一大一小for(auto num : nums){if(num<=diff){sumNumLess+=num;}}for(int i=1;i<=N;i++){if(i<=diff){sumNLess+=i;}}res.push_back(sumNLess-sumNumLess);res.push_back(sumTwo-(sumNLess-sumNumLess));return res;}
};

法三:数学运算

void FindMissingNumbers(int arr[], int n, int& num1, int& num2)
{int sum = 0;int squareSum = 0;for(int i = 0; i < n; ++i){          // 这里写的有点瑕疵,应该是"i<n-2" sum += arr[i];                 // 计算剩下n-2个数之和 squareSum += arr[i] * arr[i];  // 计算剩下n-2个数的平方和}int expectedSum = (1 + n) * n / 2;                       // 计算1~n之和 int expectedSquareSum = n * (n + 1) * (2 * n + 1) / 6;    // 计算1~n的平方和 // 假设缺失的两个数为a, b int aPlusB = expectedSum - sum;                  // a+b = expectedSum - sumint asqPlusBsq = expectedSquareSum - squareSum;    // a²+b² = expectedSquareSum - squareSumint aMulB = (aPlusB * aPlusB - asqPlusBsq) / 2;  // a*b = [(a+b)² - (a²+b²)] / 2int t = sqrt((double)aPlusB * aPlusB - 4 * aMulB);   // t = sqrt[(a+b)² - 4*a*b] = (a-b)num1 = (int)(aPlusB - t) / 2;                // num1 = (a + b - t) / 2 = bnum2 = (int)(aPlusB + t) / 2;             // num2 = (a + b + t) / 2 = a
}

消失的两个数字(1~N缺两个数)相关推荐

  1. 快速找出一个数组中的两个数字,让这两个数字之和等于一个给定的值

    我觉得写得很清晰,希望没有侵犯作者的著作权,原文地址http://blog.csdn.net/hackbuteer1/article/details/6699642 快速找出一个数组中的两个数字,让这 ...

  2. 习题:编写一个程序,请输入两个数字,并判断两个数字的大小。

    import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; /* *作者: ...

  3. 【Python实例学习】用户输入两个数字,并计算两个数字之和

    # 赋值3个参数,因为都是str,所以sum需要float转换一下num1=input('please input mum1:') num2=input('please input num2:') s ...

  4. 数据结构与算法--有序数组中找出和为s的两个数字

    有序数组中找和为s的两个数字 题目:输入一个递增排序的数组array, 和一个数字s, 在数组中找出两个数,使得这两个数的和是s,如果有多对,输出一对即可. 最简单方案 双循环,每次获取一个数据,和数 ...

  5. Java 两个数相加的测试_Java 两个数字相加

    1.两个数字相加 Java中将两个数字相加: 例如:int x = 5; int y = 6; int sum = x + y; System.out.println(sum); // 打印输出 x ...

  6. Python如何计算两个数字之和是多少?

    python是一门非常受欢迎的编程语言,具有多种优势,简单易学.用途广泛.免费开源.易读易维护.可移植,且具有丰富的库,在诸多领域都得到了广泛的应用.而在python中,求两个数的和是非常常见的需求, ...

  7. (c语言)输入两个数字,分别计算并输出这两个数字的和、差、乘积、商

    #include<stdio.h> int main(){int a,b; //定义两个数字 printf("请输入两个数\n"); scanf("%d %d ...

  8. 程序员面试金典 - 面试题 17.19. 消失的两个数字(数学/位运算)

    1. 题目 给定一个数组,包含从 1 到 N 所有的整数,但其中缺了两个数字. 你能在 O(N) 时间内只用 O(1) 的空间找到它们吗? 以任意顺序返回这两个数字均可. 示例 1: 输入: [1] ...

  9. 365天挑战LeetCode1000题——Day 096 消失的两个数字 子串能表示从 1 到 N 数字的二进制串 检查数组是否存在有效划分

    面试题 17.19. 消失的两个数字 代码实现 class Solution {public:vector<int> missingTwo(vector<int>& n ...

最新文章

  1. 稳~阿里程序员常用的 15 款开发者工具
  2. vue仿今日头条_vue2.0仿今日头条开源项目
  3. Qt开发MQTT(二) 之第三方QMQTT
  4. python数据包pandas_python_pandas学习
  5. sql更新表的字段和主键
  6. Java开发人员应该知道的前20个库和API
  7. 超经典的Android开源项目
  8. SQL中 left join 左表合并去重实用技巧
  9. 【web框架】Django
  10. Dev Grid 添加行号
  11. 《高质量程序设计指南---C++/C语言》 林锐、韩永泉
  12. 设计模式相关书籍推荐
  13. 如何利用物联网关实现智慧路灯杆组网通信
  14. 贪心+二分+快速排序
  15. 阿里服务器配置随笔记 centos 服务器 Linux 部分命令合集
  16. redis的压缩列表和跳表,看这一篇文章就够了
  17. Swift表格Lxr
  18. 如何升级展锐RM500U模组的5GCPE固件
  19. 【SQLServer】用SQL语句更改数据库名,表名,列名
  20. mars3d-canvans风向图支持自定义绘制局部区域

热门文章

  1. Android 学习(一)
  2. windows下bison安装使用
  3. 使用Dockerfile创建openoffice镜像
  4. 用计算机怎么做成绩表,利用Excel制作一个简单的学生成绩表.doc
  5. ECL、LVDS和CML电平
  6. Centos 7 x64 搭建文件服务器HFS
  7. wps的计算机在哪里设置密码,怎么在电脑版WPS中修改密码?
  8. 咸鱼前端—CSS高级技巧
  9. Java(JNI)Android使用JNI开发
  10. cab文件如何安装或者转换为exe文件?