题目描述:

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

示例 1:

输入: [1,3,4,2,2]
输出: 2
示例 2: 输入: [3,1,3,4,2]
输出: 3
说明: 不能更改原数组(假设数组是只读的)。
只能使用额外的 O(1) 的空间。
时间复杂度小于 O(n2) 。
数组中只有一个重复的数字,但它可能不止重复出现一次。

思路分析:

关键:这道题的关键是对要定位的“数”做二分,而不是对数组的索引做二分。要定位的“数”根据题意在 1 和 n 之间,每一次二分都可以将搜索区间缩小一半。

以 [1, 2, 2, 3, 4, 5, 6, 7] 为例,一共有 8 个数,每个数都在 1 和 7 之间。1 和 7 的中位数是 4,遍历整个数组,统计小于 4 的整数的个数,至多应该为 3 个,如果超过 3 个就说明重复的数存在于区间 [1,4) (注意:左闭右开)中;否则,重复的数存在于区间 [4,7](注意:左右都是闭)中。这里小于 4 的整数有 4 个(它们是 1, 2, 2, 3),因此砍掉右半区间,连中位数也砍掉。以此类推,最后区间越来越小,直到变成 1 个整数,这个整数就是我们要找的重复的数。

代码实现:

class Solution {
public static int findDuplicate(int[] nums) { int len = nums.length;
int left = 1;
int right = len - 1;
while (left < right) {
int mid = (left + right) / 2;
int count = 0;
for (int i = 0; i < len; i++) {
if (nums[i] <=mid) {
count++;
}
}
if (count > mid) {
right = mid;
} else {
left = mid + 1;
}
}
return left;
}
}

时间复杂度:O(nlogn)

空间复杂度:O(1)

最新文章

  1. iOS-语法syntax
  2. cookie封装
  3. Cloudera-Manager修改集群的IP
  4. Centos配置网卡
  5. 中国天气网-天气预报接口api
  6. WPF学习05:2D绘图 使用Transform进行控件变形
  7. Mac OS命令行运行Sublime Text
  8. 计算机语言的发展(the history of computer&#39;s language)
  9. UVA 11992 - Fast Matrix Operations(段树)
  10. css 样式 设置图片成为圆形
  11. error.go源码笔记
  12. unittest各个组件之间的关系
  13. Windows 下安装Git工具及基础使用
  14. _spellmod_aura_on_classmask
  15. Java IO,硬骨头也能变软
  16. TreeMap和TreeSet在排序时如何比较元素?Collections工具类中的sort()方法如何比较元素?
  17. 2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018) Solution
  18. es6的Set和Map数据结构
  19. Strings in the Pocket(马拉车+字符串判断)
  20. ext4文件系统由文件的inode号定位其inode Table

热门文章

  1. 南宁AI项目
  2. MySql8.0 安装重要的两步。
  3. JS中this和call
  4. 二叉树BinaryTree构建测试(无序)
  5. Forms Process (FRMWEB) Consumes 100% of CPU in Oracle Applications R12 (文档 ID 745711.1)
  6. openssl/opensslv.h错误的解决方案
  7. visual studio code(vscode) 配置在terminal进行运行代码并且支持c++11特性
  8. 计算广告(4)----搜索广告召回(也叫match、触发)
  9. SQL SERVER 查询第20行到30之间的数据
  10. 洛谷1546 最短网络Agri-Net【最小生成树】【prim】