题目:在一个长度为n的数组里的全部数字都在0到n-1的范围内。

数组中某些数字是反复的,但不知道有几个数字反复了。也不知道每一个数字反复的次数。请找出数组中随意一个反复的数字。

比如假设输入长度为7的数组{2,3,1,0,2,5,3},那么相应的输出是反复的数字2或者3.

解决问题的一个简单的方法是先把输入的数组排序。从排序的数组中找出反复的数字是件easy的事情,仅仅须要从头到尾扫描排序后的数组就能够了。排序一个长度为n的数组须要时间为O(nlogn)时间。

还能够利用哈希表来解决问题。从头到尾按顺序扫描数组中的每一个数。每扫描到一个数字的时候,都能够用O(1)的时间来推断哈希表里是否已经包括了该数字。假设哈希表里没有这个数字。就把它增加到哈希表里。

假设哈希表里已经存在该数字了,那么就找到一个反复的数字。

这个算法的时间复杂度为O(n),但它提高了时间复杂度是一个大小为O(n)的哈希表为代价的。我们再看看有没有时间复杂度为O(1)的算法。

我们注意到数组中的数字都在0到n-1的范围内的。假设这个数组中没有反复的数字。那么当数组排序后数字i将出如今下标为i的位置。因为数组中有反复的数字。有些位置可能存在数字,同一时候有些位置可能没有数字。

如今让我们重排这个数组。

从头到尾稻苗这个数组中的每一个数字。当扫描到下标为i的数字的时候。首先比較这个数字(用m表示)是不是i。假设是,接着扫描下一个数字。

假设不是,再拿它和第m个数字进行比較。

假设它和第m个数字相等。就找到一个反复的数字(该数字在下标为i和m的位置都出现了)。假设它和第m个数字不想等,就把第i个数字和第m个数字交换,把m放到属于它的位置。接下来再反复这个比較。交换的过程。直到发现一个反复的数字。

以数组{2,3,1,0,2,5,3}为例来分析找到反复数字的步骤。

数组的第0个数字(从0開始计数,和数组的下标保持一致)是2,与它的下标不想等,于是把它和下标为2的数字1交换。交换后的数组是{1,3,2,0,2,5,3}。此时第0 个数字是1,仍然与它的下标不想等,继续把它和下标为1的数字3交换,得到数组{0。1。2。3,2,5,3}。此时第0 个数字为0。接着扫描下一个数字,在接下来的几个数字中。下标为1。2。3的三个数字分别为1。2,3,他们的下标和数值都分别相等,因此不须要做不论什么操作。接下来扫描下标为4的数字2.因为它的值与它的下标不登,再比較它和下标为2的数字。

注意到此时数组中下标为2的数字也是2,也就是数字2和下标为2和下标4的两个位置了,因此找到一个反复的数字。

Java代码实现例如以下:

/**
* 数组中反复的数字
*/
package swordForOffer; /**
* @author JInShuangQi
*
* 2015年8月12日
*/
public class E51DuplicationInArray { public boolean duplicate(int[] arr){
if(arr== null || arr.length <= 0){
return false;
}
for(int i = 0;i<arr.length;i++){
if(arr[i] < 0 || arr[i] > arr.length-1)
return false;
}
for(int i = 0;i<arr.length;i++){
while(arr[i] != i){
if(arr[i] == arr[arr[i]]){
System.out.println(arr[i]);
return true;
}
else{
int temp = arr[i];
arr[i] = arr[temp];
arr[temp] = temp;
}
}
}
return false;
}
public static void main(String[] args){
int[] arr = {2,3,1,0,2,5,3};
E51DuplicationInArray test = new E51DuplicationInArray();
System.out.println(test.duplicate(arr));
}
}

. 在代码中虽然有一两个反复现年换。但每一个数字最多仅仅要交换两次就能找到属于自己的位置,因此总的时间复杂度为O(n),另外,全部的操作步骤都是在输入数组上进行。不须要额外的分配内存。因此空间复杂度为O(1).

剑指Offer面试题51(Java版):数组中反复的数字的更多相关文章

  1. 剑指Offer面试题:6.旋转数组中的最小数字

    一 题目:旋转数组中的最小数字 题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3,4,5,1,2}为{1, ...

  2. 剑指offer面试题3 二维数组中的查找(c)

    剑指offer面试题三:

  3. 剑指offer面试题3二维数组中的查找

    题目: 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 需要与面试官确认的是,这 ...

  4. 剑指offer面试题14(Java版):调整数组顺序使奇数位于偶数的前面

    题目:输入一个整数数组.实现一个函数来调整该数组中数字的顺序.使得全部奇数位于数组的前半部分.全部偶数位于数组的后半部分. 1.基本实现: 假设不考虑时间复杂度,最简单的思路应该是从头扫描这个数组,每 ...

  5. 剑指offer面试题3 二维数组中的查找 (java)

    注:java主要可以利用字符串的length方法求出长度解决这个问题带来方便 public class FindNum { public static void main(String[] args) ...

  6. 剑指offer面试题4: 二维数组中的查找

    题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数 ...

  7. 【校招面试 之 剑指offer】第11题 旋转数组中的最小数字

    题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素.例如: 数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转, ...

  8. 剑指Offer - 九度1384 - 二维数组中的查找

    剑指Offer - 九度1384 - 二维数组中的查找2013-11-23 23:23 题目描述: 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个 ...

  9. 剑指offer【01】- 二维数组中的查找(Java)

    在经历了春招各大公司的笔试题和面试官的血虐之后,决定要刷一些算法题了,不然连面试机会都没有. 而应对笔试和面试,比较出名的就是剑指offer的题目和LeetCode的题目了.剑指offer应对面试中的 ...

随机推荐

  1. 安装的 Python 版本太多互相干扰?pyenv 建议了解一下。

    写在之前 我们都知道现在的 Python 有 Python2 和 Python3,但是由于各种乱七八糟的原因导致这俩哥们要长期共存,荣辱与共,尴尬的是这哥俩的差异还比较大,在很多时候我们可能要同时用到 ...

  2. 观数据世界,览类型风骚---Python

    一.变量的简介 变量只不过是保留的内存位置用来存储数据.这意味着,当创建一个变量,那么它在内存中保留一些空间. 根据一个变量的数据类型,解释器分配内存,并决定如何可以被存储在所保留的内存中.因此,通过 ...

  3. TOJ 3974: Region n条直线m个圆最多将圆分为几个区域

    3974: Region  Time Limit(Common/Java):1000MS/3000MS     Memory Limit:65536KByteTotal Submit: 33     ...

  4. 查找docker log久远数据方法

    问题描述: 同事发现几天前运行的一个文件id存在错误,需要查看docker log,但是使用docker logs -f container_id 上下翻很耗费时间. 解决思路: 每条对应的log都会 ...

  5. .net学习笔记--设计模式

    设计模式都有哪些? 按照GOF提出,23种,按照目的分为:创建型(creational).结构性(structural).行为型(behavioral). 一.创建型: 1.Singleton 单例模 ...

  6. log4net实现多实例记录

    原文地址:实现多个LOG4NET日志记录器实例 本文内容为摘抄,请查看原文. 对于.NET Framework开发者来说,使用Log4Net进行日志记录是非常方便的,通常只要写好配置文件和简单的编码就 ...

  7. Event Loop详解

    1.进程,单线程与多线 进程: 运行的程序就是一个进程,比如你正在运行的浏览器,它会有一个进程. 线程: 程序中独立运行的代码段. 一个进程由单个或多个线程组成,线程是负责执行代码的. 2.单线程与多 ...

  8. BZOJ 4070 [Apio2015]雅加达的摩天楼 ——分块 SPFA

    挺有趣的分块的题目. 直接暴力建边SPFA貌似是$O(nm)$的. 然后考虑分块,$\sqrt n$一下用虚拟节点辅助连边, 以上的直接暴力连边即可. 然后卡卡时间,卡卡空间. 终于在UOJ上T掉辣. ...

  9. BZOJ2132 圈地计划 【最小割】

    题目 最近房地产商GDOI(Group of Dumbbells Or Idiots)从NOI(Nuts Old Idiots)手中得到了一块开发土地.据了解, 这块土地是一块矩形的区域,可以纵横划分 ...

  10. FZU 2168 前缀和+dp递推

    Description   部队中共有N个士兵,每个士兵有各自的能力指数Xi,在一次演练中,指挥部确定了M个需要防守的地点,按重要程度从低到高排序,依次以数字1到M标注每个地点的重要程度,指挥部将选择 ...