消失的两个数字(1~N缺两个数)
问题描述
给定一个数组,包含从 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缺两个数)相关推荐
- 快速找出一个数组中的两个数字,让这两个数字之和等于一个给定的值
我觉得写得很清晰,希望没有侵犯作者的著作权,原文地址http://blog.csdn.net/hackbuteer1/article/details/6699642 快速找出一个数组中的两个数字,让这 ...
- 习题:编写一个程序,请输入两个数字,并判断两个数字的大小。
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; /* *作者: ...
- 【Python实例学习】用户输入两个数字,并计算两个数字之和
# 赋值3个参数,因为都是str,所以sum需要float转换一下num1=input('please input mum1:') num2=input('please input num2:') s ...
- 数据结构与算法--有序数组中找出和为s的两个数字
有序数组中找和为s的两个数字 题目:输入一个递增排序的数组array, 和一个数字s, 在数组中找出两个数,使得这两个数的和是s,如果有多对,输出一对即可. 最简单方案 双循环,每次获取一个数据,和数 ...
- Java 两个数相加的测试_Java 两个数字相加
1.两个数字相加 Java中将两个数字相加: 例如:int x = 5; int y = 6; int sum = x + y; System.out.println(sum); // 打印输出 x ...
- Python如何计算两个数字之和是多少?
python是一门非常受欢迎的编程语言,具有多种优势,简单易学.用途广泛.免费开源.易读易维护.可移植,且具有丰富的库,在诸多领域都得到了广泛的应用.而在python中,求两个数的和是非常常见的需求, ...
- (c语言)输入两个数字,分别计算并输出这两个数字的和、差、乘积、商
#include<stdio.h> int main(){int a,b; //定义两个数字 printf("请输入两个数\n"); scanf("%d %d ...
- 程序员面试金典 - 面试题 17.19. 消失的两个数字(数学/位运算)
1. 题目 给定一个数组,包含从 1 到 N 所有的整数,但其中缺了两个数字. 你能在 O(N) 时间内只用 O(1) 的空间找到它们吗? 以任意顺序返回这两个数字均可. 示例 1: 输入: [1] ...
- 365天挑战LeetCode1000题——Day 096 消失的两个数字 子串能表示从 1 到 N 数字的二进制串 检查数组是否存在有效划分
面试题 17.19. 消失的两个数字 代码实现 class Solution {public:vector<int> missingTwo(vector<int>& n ...
最新文章
- 稳~阿里程序员常用的 15 款开发者工具
- vue仿今日头条_vue2.0仿今日头条开源项目
- Qt开发MQTT(二) 之第三方QMQTT
- python数据包pandas_python_pandas学习
- sql更新表的字段和主键
- Java开发人员应该知道的前20个库和API
- 超经典的Android开源项目
- SQL中 left join 左表合并去重实用技巧
- 【web框架】Django
- Dev Grid 添加行号
- 《高质量程序设计指南---C++/C语言》 林锐、韩永泉
- 设计模式相关书籍推荐
- 如何利用物联网关实现智慧路灯杆组网通信
- 贪心+二分+快速排序
- 阿里服务器配置随笔记 centos 服务器 Linux 部分命令合集
- redis的压缩列表和跳表,看这一篇文章就够了
- Swift表格Lxr
- 如何升级展锐RM500U模组的5GCPE固件
- 【SQLServer】用SQL语句更改数据库名,表名,列名
- mars3d-canvans风向图支持自定义绘制局部区域