给定一个长度为n-1的整形数组,数字的范围在1到n(无重复),其中有一个缺失的数字,写一段高效的程序找出该数字。

一、数组有序

对于该数组是否有序,题目没有说明,假设有序,则可使用二分查找,时间复杂度为O(logN)。
如果中间元素的值和下标相等,那么下一轮查找只需要查找右半边;如果中间元素的值和下标不相等,并且它前面一个元素和它的下标相等,这意味着这个中间的数字正好是第一个值和下标不相等的元素,它的下标就是在数组中不存在的数字;如果中间元素的值和下标不相等,并且它前面一个元素和它的下标不相等,这意味着下一轮查找我们只需要在左半边查找即可。
参考代码:

int getLoseNum(int a[], int left, int right)
{int mid;while(left <= right){mid = (left + right) / 2;if(a[mid] == mid + 2) //缺失的数据在后半部分right = mid - 1;else if(a[mid] == mid + 1)  //缺失的数据在前半部分left = mid + 1;}return left + 1;
}

二、与数组顺序无关

以下方法,数组是否有序都可使用,但一中的二分查找,要求数组必须有序。

1、求和法

用1+2+…+n减去当前输入数据的总和,则所得的差就是缺失的那个数。
时间复杂度:O(n) 空间复杂度:O(1)。但n过大时,求和存在溢出问题。

//n:最大元素的值而不是元素的个数
int getNum(int a[], int n)
{int sum = n*(n+1)/2;int t;for(int i=0; i<n-1; i++){sum = sum - a[i];}return sum;
}

2、异或法

利用异或运算,
任何数异或自己都等于0,x^x=0,任何数异或0都等于他自己x^0=x;
假如缺的为3。result = 1^2^4^5^N
第二次异或后 result = 1^2^4^5^N ^1^2^3^4^5^N = 0^3 = 3
时间复杂度:O(n) 空间复杂度:O(1)
参考代码:

//异或方法,n:最大元素的值
int getLose(int a[], int n)
{int t = 0;for(int i =1; i<=n; i++)t = t ^ i;//最大值为n,缺失一个元素,则元素个数为n-2for(int i=0; i<n-1; i++)t = t ^ a[i];return t;
}

3、hash方法

对输入数据进行Hash,然后从头到尾遍历一次。时间复杂度O(n) 空间复杂度O(n)
参考代码:

//max:最大值
int getMiss(int a[], int max)
{//hash表的长度比max大1int *tmp = new int[max+1];//数组的值从1开始,因此hash表的0位不用for(int i=1; i<=max; i++)tmp[i] = 0;//对数组遍历,缺失一个数,数组的长度为max-2for(int i=0; i<max-1; i++){tmp[a[i]]++;}for(int i=1; i<=max; i++)if(tmp[i] == 0)return i;
}
int main()
{int a[] = {1,2,3,4,5,7};cout<<getLoseNum(a, 0, 6)<<endl;cout<<getNum(a, 7)<<endl;cout<<getLose(a, 7)<<endl;cout<<getMiss(a, 7)<<endl;return 0;
}

二、题目扩展:数组中缺失两个数?

同样的可以用两种方法:
1、对数据从min~max求和,为S1;并且求出数组中所有元素的和,为S2;
记缺失的数据为a,b。S1-S2=a+b;
那么a、b,一定是一个比(a+b)/2小,一个比它大。再遍历一遍数组,以(a+b)/2为分界线,较小的加为Smin,较大的加为Smax。求出min~(a+b)/2和(a+b)/2~max的和,相减就可以得到两个数了。
2、将数组中的元素全部进行异或运算,再异或上min^(min+1)^….^max,这样就得到了a^b,记为c。由于a!=b。所以c!=0;那么一定有一位是1.用d=(c-(c&(c-1)))就可以得到c的最右边的为1的位,以这一位为分界线,为1的分为一组,不为1的分成另一组,然后求min~d和d~max的异或,再分别异或上刚刚分好的两组数据。这样就将问题转化成问题1的情况了。那a、b自然也就出来了。
扩展部分参考:
http://www.cnblogs.com/prajna/archive/2013/02/25/2932807.html
https://blog.csdn.net/nature_XD/article/details/51999793

找1到n中缺失的数字(长度为n-1的整形数组,数字的范围在1到n,找其中一个缺失的数字)相关推荐

  1. isalnum()函数:找出str字符串中为英文字母或数字的字符

    找出str字符串中为英文字母或数字的字符 (1)Linux下编程用到的函数是:int isalnum(int c) 返回值:若参数c为字母或数字,则返回TRUE:否则返回NULL(0) #includ ...

  2. 把一个整形数组中重复的数字去掉 - 微软面试题

    请把一个整形数组中重复的数字去掉.例如:  1,   2,   0,   2,   -1,   999,   3,   999,   88  答案应该是: 1,   2,   0,   -1,   9 ...

  3. C语言习题:输入10个学生5门课的成绩,分别用函数求:①每个学生平均分;②每门课的平均分;③找出所有分数中最高分

    初学C语言,然后遇到一题: 输入10个学生5门课的成绩,分别用函数求:①每个学生平均分:②每门课的平均分:③找出所有分数中最高分 直接上代碼 注:自定义函数(xpj,kpj,maxj)我直接放在最前面 ...

  4. 一道google面试题--自然数e中出现的连续的第一个10个数字组成的质数

    博客内容移到 http://www.linuxyu.com/ 此CSDN博客将不再更新,欢迎大家访问新的网站~~ Google早几年在美国很多地铁的出站口都有大幅招聘广告,它的第一题如下了:{firs ...

  5. Leecode:给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。假设只有一个重复的整数,找出这个重复的数

    题目 /** * 给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数.假设只有一个重复的整数,找出这个重复的数. * 示例 ...

  6. 找对象的过程中,我竟然理解了什么是机器学习!

    最近开始了有关机器学习方面知识的学习,自己啃书本的时候一些概念枯燥无味,所以借着做笔记的机会来简单理解其中的一些概念,如有谬误,还望指出.? 什么是人工智能? 我看过很多博客解释什么是人工智能,我觉得 ...

  7. 从自动贩卖机找零看Python中的动态规划问题

    原文:http://www.jianshu.com/p/144db81341a3 从自动贩卖机找零看Python中的动态规划问题 问题描述 假设在某国存在[1,x1,x2,x3,...,xn]多种货币 ...

  8. 算法试题 - 找出字符流中第一个不重复的元素

    题目 题目:请实现一个函数用来找出字符流中第一个只出现一次的字符.例如,当从字符流中只读出前两个字符"go"时, 第一个只出现一次的字符是"g".当从该字符流中 ...

  9. Java中怎么样检查一个字符串是不是数字呢

    问题:Java中怎么样检查一个字符串是不是数字呢 在解析之前,怎么样检查一个字符串是不是数字呢 回答一 这些通常是由一个简单的用户自定义函数去解决的(即,自带的 "isNumeric&quo ...

  10. Android 引用模块中的类,解决Android项目中找不到Module中的封装类或引用的第三方类库...

    在日常开发中,现在越来越流行模块化开发,这就需要将项目分成不同的Module进行同时开发,最后在app层进行整合调用,但是不少开发人员都因为在build中添加关联代码,而找不到Module中封装的方法 ...

最新文章

  1. 内蒙古公安原创扫黑除恶主题MV《以警之名》全国首发
  2. umask及文件默认和原始权限说明
  3. Android之实现多张图片点击预览(支持放缩)和滑动
  4. Maven——profile介绍
  5. 【Flink】Flink连接prometheus报错 IOException :Response code formxxx/metrics/job/rule
  6. 如何修改magento产品详细页面的栏目
  7. 深入浅出数据中心里的OpenStack
  8. 项目中为什么用Docker?
  9. 使用VC做一个简单的UI界面对话框
  10. 数据分析方法论(一)
  11. July:海量数据处理
  12. [转]王飞跃:交通拥堵多因管理水平等所致
  13. 爬取Bilibili视频评论,并生成云词图
  14. linux系统外接硬盘_电脑主硬盘linux系统,外接硬盘win7系统.如何启动外接硬盘的win7系统?...
  15. pc 端与移动端区分点击与拖拽事件
  16. 2022年数维杯国际赛C题 如何利用大脑结构诊断阿尔茨海默氏病
  17. 因果推断系列17 - 合成控制法
  18. Win10系统安装SQL 2010教程
  19. python生成图云遇到生成框框的错误
  20. #UI+前端#(六)动效形成(wow.js)

热门文章

  1. 线性代数之——正定矩阵
  2. fash 3D 游戏
  3. GROMACS Tutorial 3-Umbrella Sampling
  4. 谢烟客-----计算机基础
  5. MySQL数据库:表结构优化
  6. JavaScript 对象的创建与继承——创建篇
  7. Oralce ERP中AP模块Vender银行信息查询语句
  8. html 格式化日期
  9. 漫画制作软件EasyComic V1.7发布
  10. Recovering High Dynamic Range Radiance Maps from Photographs