对于一个长度为n+1的数组,其中每一个值的取值范围是[1,n],可以证明的是必然存在一个重复数字(抽屉原理),假设仅存在一个重复数字,找到他。

举例:输入:[1,3,4,2,1],输出:1

自己做的时候,要么时间复杂度到o(n2),要么需要额外的存储空间利用hashset,下面来分析一下leetcode上别人的算法吧。

方法一:通过图论中环的有关知识解决

public int findDuplicate(int[] nums) {
// Find the intersection point of the two runners.
int tortoise = nums[0];
int hare = nums[0];
do {
tortoise = nums[tortoise];
hare = nums[nums[hare]];
} while (tortoise != hare); // Find the "entrance" to the cycle.
int ptr1 = nums[0];
int ptr2 = tortoise;
while (ptr1 != ptr2) {
ptr1 = nums[ptr1];
ptr2 = nums[ptr2];
} return ptr1;
}

如果数组的每一个数的取值都是不重复的,那么可以选取特定的数值来使,不断通过索引值得到数值,再将新的数值作为索引值,循环下去可以得到一个链路。假定数组为[1,2,3,4,5],设定f(x),x是索引值,f(x)是值,并将得到的f(x)作为下一个输入,这样形成了一个链路,1->2->3->4->5;但是如果稍微做一下改变原数组为[1,2,3,4,1],那么链路将变为,1->2->3->4->1…,形成一个环路,这里的重复数字1就是构成环路的关键。

本题中就包含这样一个重复数字,所以数组nums一定会存在一个环路,问题变为如何查找环路起点问题,对于这种问题有这样一个算法,叫做弗洛伊德的循环寻找算法。在算法中会有两个指针一个快速指针每次移动两个步骤,一个慢速指针每次移动一个步骤,其中快速指针会提前进入循环并且在慢速指针进入循环后会与其相交。类似于操场跑圈,快速指针和慢速指针同时同宿舍出发,快速指针先到操场开始跑圈,慢速指针后到操场开始跑圈,但是快速指针一定会在某个时刻与慢速指针到达同一位置。

如何求取圆环起点位置(即重复的数字):

设定慢速指针与快速指针相交点距离环起点的距离为k,环周长为n,指针起点到环起点的距离为m,则慢速指针走过的距离为a = m+k+xn ;快速指针走过的距离为2a = m+k+yn,两者做差可以得到a = (y-x)n,是环长度的整数倍,如果将快速指针重置到起点,且将快速指针的移动距离改为1,那么当快速指针移动到圆环起点时,慢速指针移动距离为a+m,因为a是圆环长度的整数倍,所以慢速指针的位置也是在圆环起点,这样两者的相遇点即为圆环起点。

方法二:

    public int findDuplicate_leetcode3(int[] nums) {
if (nums.length == 0 || nums == null)
return 0;
int low = 1, high = nums.length - 1, mid;
while (low < high) { //这个题不好用low+1<high,因为最后结果的两个值无从比较,是基于count的
mid = low + (high - low) / 2;
int count = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] <= mid)
count++;
}
if (count > mid)
high = mid;
else
low = mid + 1;
}
return low;
}

根据题目中的条件,可以知道的是一定会有重复数字且只有一个重复数字,那么必然导致数组数值的不均匀分布(指的不是位置的不均匀,而是数值的取值不均匀),那么可以通过二分法来判别重复取值的数字在哪个部分,取数组的中值,计算大于和小于中值的数量,取数量较多的那份为新的数组,重复进行,最后到不可分时,得到的即为重复数字。

Find the Duplicate Number (寻找重复数字)的更多相关文章

  1. [LeetCode] Find the Duplicate Number 寻找重复数

    Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), pro ...

  2. [LeetCode] 287. Find the Duplicate Number 寻找重复数

    Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), pro ...

  3. [LeetCode] Find Duplicate Subtrees 寻找重复树

    Given a binary tree, return all duplicate subtrees. For each kind of duplicate subtrees, you only ne ...

  4. 287 Find the Duplicate Number 寻找重复数

    一个长度为 n + 1 的整形数组,其中的数字都在 1 到 n 之间,包括 1 和 n ,可知至少有一个重复的数字存在.假设只有一个数字重复,找出这个重复的数字.注意:    不能更改数组内容(假设数 ...

  5. LeetCode Find the Duplicate Number 找重复出现的数(技巧)

    题意: 有一个含有n+1个元素的数组,元素值是在1-n之间的整数,请找出其中出现超过1次的数.(保证仅有1个出现次数是超过1的数) 思路: 方法一:O(nlogn).根据鸽笼原理及题意,每次如果< ...

  6. LeetCode 287. Find the Duplicate Number (找到重复的数字)

    Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), pro ...

  7. 287. Find the Duplicate Number 找出数组中的重复数字

    [抄题]: Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive ...

  8. 64.Find the Duplicate Number(发现重复数字)

    Level:   Medium 题目描述: Given an array nums containing n + 1 integers where each integer is between 1 ...

  9. Leetcode之二分法专题-287. 寻找重复数(Find the Duplicate Number)

    Leetcode之二分法专题-287. 寻找重复数(Find the Duplicate Number) 给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和  ...

随机推荐

  1. 克隆对象__clone()方法

    有的时候我们需要在一个项目里面,使用两个或多个一样的对象,如果你使用“new”关键字重新创建对象的话,再赋值上相同的属性,这样做比较烦琐而且也容易出错,所以要根据一个对象完全克隆出一个一模一样的对象, ...

  2. Handlebars.js中集合(list)通过中括号的方式取值

    有这么一个需求,在一个table中,tr是通过each取值,取出的值要与table标题相对应,如何实现?例如: <table> <thead> <tr> {{#ea ...

  3. December 11th 2016 Week 51st Sunday

    If a thing is worth doing it is worth doing well. 如果事情值得做,那就做好. If it is worth doing, then it is wor ...

  4. myeclipse 2013破解注册图文教程

    以下这个试过有效 http://www.33lc.com/article/10792.html

  5. 防止开放重定向,恶意篡改returnUrl

    1.防止开放重定向: /// <summary> /// 防止开放重定向 /// </summary> /// <param name="url"&g ...

  6. 联想Thinkpad 遇到双系统 uefi Ubuntu无法进入的引导问题解决方案

    最近因为许多课程设计的需要,安装了Ubuntu双系统,但是一开始遇到了安装好了以后无法进入的问题,后来弄好后手残又把引导项给删了又要弄回去,反反复复很多次,网上的很多经验都十分过时,要么对最新的uef ...

  7. BZOJ1058:[ZJOI2007]报表统计(Splay,堆)

    Description 小Q的妈妈是一个出纳,经常需要做一些统计报表的工作.今天是妈妈的生日,小Q希望可以帮妈妈分担一些工 作,作为她的生日礼物之一.经过仔细观察,小Q发现统计一张报表实际上是维护一个 ...

  8. P2986 [USACO10MAR]伟大的奶牛聚集Great Cow Gat…

    题目描述 Bessie is planning the annual Great Cow Gathering for cows all across the country and, of cours ...

  9. P1346 电车

    题目描述 在一个神奇的小镇上有着一个特别的电车网络,它由一些路口和轨道组成,每个路口都连接着若干个轨道,每个轨道都通向一个路口(不排除有的观光轨道转一圈后返回路口的可能).在每个路口,都有一个开关决定 ...

  10. SpringMVC如何解决POST请求中文乱码问题,GET的又如何处理呢?

    在web.xml中 <filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-c ...