Find the Duplicate Number

原题链接Find the Duplicate Number

给定一定大小为n+1的数组,数组中的元素只可能是1到n中的数字,包括1和n。在数组中,有一个数字重复了多次,找到这个数字。
要求不能改变源数组的值,空间复杂度为O(1),时间复杂度要小于O(n2)。

注意数组中每个元素都只能是1到n之间的数字,这提供了一个有用的信息,即

  • 对于每个元素,可以用它的大小和[1: n]之间的数字比较

什么意思呢,假设数组中只有n个元素,而每个元素的大小都在[1 : n]之间,且没有重复元素。那么对于1到n中的某个值w而言,整个数组中小于等于w的元素个数恰好等于w。可以通过先将数组排序后证明

接着,n个元素的时候恰好[1 : n]各一个,现在,随机从[1 : n]中选择一个数字添加到数组中,使数组元素个数变为n+1。此时,对于某个值w而言。如果添加的数字小于等于w,那么小于等于w的元素个数将大于w(因为添加前是等于w)。反之,如果添加的数字大于w,那么小于等于w的元素个数将小于w。

现在,假设数组元素个数为n+1,因为数组元素只有n中取值,所以数组中会有重复元素,可能重复多次。那么此时对于1到n+1中的某个值w而言,整个数组中小于等于w的元素个数就会有三种可能

  • 数组中小于等于w的元素个数恰好等于w。这可以说明在数组所有元素中,值在[1 : w]这个范围内的元素没有重复,重复元素在[w + 1 : n]中

    • 证明,反证法。如果有重复元素,那么[w + 1 : n]这个范围内的元素将不会重复,那么数组中元素总个数为w + (n - w - 1 + 1) = n。而实际上数组元素个数为n+1,矛盾。
  • 数组中小于等于w的元素个数小于w。这可以说明在数组所有元素中,值在[1 : w]这个范围内的元素没有重复,重复元素在[w + 1 : n]中

    • 证明,反证法。因为小于等于w的元素个数小于w,所以大于w的元素个数大于n + 1 - w。如果[w + 1 : n]没有重复元素,那么大于w的元素个数最多为n - w,矛盾。
  • 数组中小于等于w的元素个数大于w。这可以说明在数组的所有元素中,重复元素在[1 : w]中

    • 证明,反证法。如果[1 : w]范围内没有重复的元素,那么小于等于w的元素个数最多为w,不可能大于w,矛盾。

通过这种划分,让上述w取当前区间的中值,就可以采用二分法找到重复的那个元素,代码如下

class Solution {
public:int findDuplicate(vector<int>& nums) {int left = 1;int right = nums.size();while(left < right){/* 取区间的中值作为w */int middle = left + (right - left) / 2;int count = 0;/* 计算数组中所有小于等于w的元素个数 */for(auto n : nums){if(n <= middle)++count;}/* 如果个数小于等于w,说明重复元素在[w+1 : n]的范围内 */if(count <= middle)left = middle + 1;elseright = middle;}return left;}
};

其实仔细想一下,时间复杂度小于O(n2)的无非O(1),O(lgn),O(n),O(nlgn)几种,又要求空间复杂度是O(1),那么O(n)之前的几乎都没戏了,所以只可能是O(nlgn)。又因为O(lgn)通常和二分法联系在一起,所以很明显需要使用二分法。又因为数组元素在[1 : n]之间,所以可以用数组大小和下标作比较,即通过比较然后利用二分缩小范围。

每天一道LeetCode-----给定大小为n+1的数组,元素大小在[1 : n]之间,只有一个元素会重复出现多次,找到重复的那个相关推荐

  1. 去掉数组最后一个元素_leetcode 34. 在排序数组中查找元素的第一个和最后一个位置每天刷一道leetcode算法系列!...

    作者:reed,一个热爱技术的斜杠青年,程序员面试联合创始人 前文回顾: leetcode1. 两数之和--每天刷一道leetcode系列! leetcode2. 两数相加--每天刷一道leetcod ...

  2. mysql备份文件0kb_Oracle 数据文件大小为0kb或者文件丢失恢复

    接到一个朋友恢复请求,由于rose频繁切换导致文件系统部分数据文件变化为0kb和文件丢失. 故障现象 部分数据文件变化为0kb和文件丢失. 这里比较明显,数据库的users03变为了0kb和users ...

  3. 每天一道LeetCode-----找到由连续数字组成的数组中缺失的那个连续值

    原题连接Missing Number 给定大小为n的数组,由0, 1, 2, -, n构成,其中缺少了某个值,找到它.要求时间复杂度是O(n),空间复杂度是O(1) 虽然数组无序但是组成数组的元素整体 ...

  4. 32位计算机分配的最大内存大小,win732位内存支持多大内存 win732位内存最大支持大小【图文】...

    内存是计算机中非常重要的一个硬件,内存的大小直接影响到系统能够支持同时运行程序的数量和质量,而且还能够支持运行占用资源较大的软件.而对于不同的系统,它所能够支持的最大内存数量也会有区别的.那么我们生活 ...

  5. leetcode 169(简单)题解:给定一个大小为 *n* 的数组,找到其中的多数元素。多数元素是指在数组中出现次数大于 *⌊ n/2 ⌋* 的元素。

    署名:csdn等网站博客copy产出,AI时代知识新搬运工 言归正传:写下这道题的个人理解 题干: 给定一个大小为 n 的数组,找到其中的多数元素.多数元素是指在数组中出现次数大于 ⌊ n/2 ⌋ 的 ...

  6. 给定一个大小为 *n* 的数组,找到其中的多数元素。多数元素是指在数组中出现次数大于 *⌊ n/2 ⌋* 的元素。

    多数元素 给定一个大小为 n 的数组,找到其中的多数元素.多数元素是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素. 你可以假设数组是非空的,并且给定的数组总是存在多数元素. 示例 1: 输入: [3 ...

  7. 给定数组A,大小为n,现给定数X,判断A中是否存在两数之和等于X

    1. 问题描述 给定排的数组A,大小为n,现给定数X,判断A中是否存在两数之和等于X.给出一个O(nlg(n))的算法. 2. 解决思路 首先对数组进行排序,如果使用归并的排序的话,算法的复杂度在nl ...

  8. 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。

    /*** 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2.请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))=Ologm*Ologn.你可以假设 ...

  9. 【八皇后】给定一个大小为 n 的正方形国际象棋棋盘,求有多少种方式可以放置 n 个皇后并使得她们互不攻击,即每一行、列、左斜、右斜最多只有一个皇后。

    给定一个大小为 n 的正方形国际象棋棋盘,求有多少种方式可以放置 n 个皇后并使得她们互不攻击,即每一行.列.左斜.右斜最多只有一个皇后. 输入是一个整数 n,输出是一个整数 m,表示所有的棋盘表示方 ...

最新文章

  1. debian 10 ssh简单配置
  2. 论文:Insights on Transfer Optimization: Because Experience is the Best Teacher(1)文章结构以及以及自己的感觉
  3. 如何用纯 CSS 创作一个精彩的彩虹 loading 特效
  4. 《java入门第一季》之面向对象面试题(继承中构造方法的关系)
  5. JavaScript表达式--掌握最全的表达式,一切尽在掌握中,让表达不再是难事
  6. 使用JIRA搭建企业问题跟踪系统(转)
  7. 图卷积网络初探【GCN】
  8. 教师计算机应用研讨交流,计算机应用技术专业技能比赛研讨交流活动在济南信息工程学校举行...
  9. 即将到来的“分布式云”(DPaaS):分布式计算+ DB +存储即服务
  10. 面试字节跳动社招,我工资涨了60%,附带面经
  11. linux迅雷下载命令,命令行也强大之下载迅雷资源的方法
  12. Linux网络参数DD,linux tcpdump命令参数及用法详解--linux下抓包网络分析
  13. 适配器模式和代理模式的区别
  14. __wakeup()绕过
  15. 关于“外接硬盘被写了保护的解决方法”
  16. js正则表达式匹配纯中文或纯英文
  17. C++快慢指针理解与应用
  18. 南京印象之出租车司机
  19. 首师大附中科创教育平台 我的刷题记录 0324 99999999海岛帝国:运输资源
  20. 关于解决Carsim2016找不Liscens问题的原生BIA法

热门文章

  1. java date 最小值_java – Datepicker和timepicker – 设置最大值和最小值
  2. Java黑皮书课后题第10章:*10.11(几何:Circle2D类)定义Circle2D类
  3. Java黑皮书课后题第10章:*10.1(Time类)设计一个名为Time的类。编写一个测试程序,创建两个Time对象(使用new Time()和new Time(555550000))
  4. Java黑皮书课后题第1章:1.2(显示五条消息)编写程序,显示以下表格
  5. PC网页实现九宫格切图功能
  6. 3-5 获取命令行参数
  7. java 中 的 字节流!
  8. HDU1425 A Chess Game
  9. 20169214 2016-2017-2 《网络攻防实践》实验二学习总结
  10. 10.30 NFLS-NOIP模拟赛 解题报告