题目1:找出数组中重复的数字

【题目描述】

在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字

例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是重复的数字2或者3。

【思路】

方法1:先排序,后比较

最简单直接的方式,先对数组进行排序,然后从头到尾扫描数组。时间复杂度为O(nlogn),空间复杂度为O(1).

方法2:哈希表

如何进一步降低空间复杂度? 可以采用哈希表。

从头到尾扫描整个数组,每扫描一个数字的时候先判断hash table中是否已经包含该数字,如果包含,则找到重复的数字;如果不包含,则将该数字加入到hash table中。

时间复杂度为O(n),空间复杂度为O(n)。

方法3:位置交换

如何在保证低空间复杂度的情况下,降低空间复杂度?我们可以通过题目设定的条件进一步思考。

审题可知数组中总共有n个数字,并且这n个数字的取值范围是[0, n-1],也就是说,如果整个数组没有重复数字的话,那么每个数字 i 都可以放到第 i+1 的位置上。相反,如果有重复数字出现,那么这样的存放方法是不可行的。基于这一考虑,我们可以采用如下办法: 从左到右扫描数组A,对于位置 $i \in [0, n-1]$, 如果$A[i] = i$, 则继续扫描下一位置 i+1;如果$A[i] \neq i$, 则比较数字A[i]与位置A[i]上的数字,如果相等,说明出现重复数字A[i],如果不等,则将两个数字置换,然后再次对位置 i上的数字重复上述操作。

 

题目2:不修改数组找出重复的数字

【题目描述】

在一个长度为n+1的数组里的所有数字都在1到n的范围内,所以数组中至少有一个数字是重复的。请找出数组中任意一个重复的数字,并且不能修改输入的数组。

例如,如果输入长度为8的数组{2,3,5,4,3,2,6,7},那么对应的输出是重复的数字2或者3。

【思路】

方法1:把数字插入到辅助数组

与题目1类似,但是要求不能改变原始数组,因此我们可以采用题目1中的方法3类似的思想(i.e. 让数字归位到对应的index上)。创建一个辅助数组,将原数组中的数字依次放入到辅助数组中对应的位置上,这样很容易发现那个数字是重复的。时间复杂度为O(n),空间复杂度为O(n)。

方法2:二分查找统计

如何避免使用O(n)的辅助空间呢?

将数字1~n从中间数字m分成两部分,前一半为1~m,后一半为m+1~n。在数组中检索1~m这几个数字出现的次数之和(即1<= x <=m),如果数目超过m,说明这一半区间内肯定包含重复数字,否则重复数字肯定包含在另一半内。接下来,可以继续把包含重复数字的区间一分为二,直到找到某个重复的数字。

二分的次数为O(logn),每次需要O(n)的时间来统计数字出现次数,因此总时间复杂度为O(nlogn),空间复杂度为O(1)。

需要注意的是,该方法不能保证找出所有重复的数字。比如{2,3,5,4,3,2,6,7},不能找出重复数字2,因为1~2中只有2个数字,并且该范围内的数字也只出现了2次。

No.3 数组中重复的数字 (P39)的更多相关文章

  1. 【Java】 剑指offer(1) 找出数组中重复的数字

    本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 在一个长度为n的数组里的所有数字都在0到n-1的范围内.数组中某些数字 ...

  2. 《剑指offer》第三_一题(找出数组中重复的数字,可改变数组)

    // 面试题3(一):找出数组中重复的数字 // 题目:在一个长度为n的数组里的所有数字都在0到n-1的范围内.数组中某些数字是重复的,但不知道有几个数字重复了, // 也不知道每个数字重复了几次.请 ...

  3. 剑指offer35题:第一个只出现一次的字符+剑指offer55题:字符流中第一个不重复的字符+剑指offer51题:数组中重复的数字

    在看剑指offer的时候,感觉这三个题目很像,都是用哈希表可以解决,所以把这三个题整理出来,以供复习. 剑指offer35题:第一个只出现一次的字符 题目描述:在字符串中找出第一个只出现一次的字符.如 ...

  4. 剑指Offer(书):数组中重复的数字

    题目:找出数组中重复的数字. 说明:在一个长度为n的数组里的所有数字都在0~n-1的范围内,数组中某些数字是重复的,但是不知道有几个数字重复了,也不知道每个数字重复了几次.请找出数组中任意一个重复的数 ...

  5. JavaScript去除数组中重复的数字

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  6. 【剑指Offer】面试题03. 数组中重复的数字

    题目 找出数组中重复的数字. 在一个长度为 n 的数组 nums 里的所有数字都在 0-n-1 的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次.请找出数组中任意 ...

  7. leetcode题库练习_数组中重复的数字

    题目:数组中重复的数字 找出数组中重复的数字. 在一个长度为 n 的数组 nums 里的所有数字都在 0-n-1 的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次 ...

  8. 剑指offer数组中重复的数字

    package 数组; /*在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的. 也不知道每个数字重复几次.请找出数组中任意一个重复的数字. ...

  9. 剑指offer二刷——数组专题——数组中重复的数字

    题目描述 在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度为 ...

随机推荐

  1. 【ZCTF】easy reverse 详解

    0x01  前言     团队逆向牛的解题思路,分享出来~ 0x02  内容 0. 样本 bbcdd1f7-9983-4bf4-9fde-7f77a6b947b4.dll 1. 静态分析 使用IDAP ...

  2. Javascript高级编程学习笔记(72)—— 模拟事件(2)IE事件模拟

    IE中的事件模拟 低版本的IE浏览器作为前端开发的一股清流,想避过都不行 虽然低版本IE正在逐步被市场淘汰,不得不承认IE8以下的浏览器依然占了不小的份额 所以这里大概介绍IE8以下的低版本IE中的事 ...

  3. 微信小程序 - 相对定位和绝对定位 - 相对路径和绝对路径

    微信小程序 - 相对定位和绝对定位 相对定位relative,绝对定位absolute 相对定位:元素是相对自身进行定位,参照物是自己. 绝对定位:元素是相对离它最近的一个父级元素进行定位. 相对定位 ...

  4. 把ajax包装成promise的形式(3)

    概述 为了体验promise的原理,我打算自己把ajax包装成promise的形式.主要希望实现下列功能: // 1.使用success和error进行链式调用,并且可以在后面加上无限个 promis ...

  5. 《http权威指南》读书笔记7

    概述 最近对http很感兴趣,于是开始看<http权威指南>.别人都说这本书有点老了,而且内容太多.我个人觉得这本书写的太好了,非常长知识,让你知道关于http的很多概念,不仅告诉你怎么做 ...

  6. CSS3 Gradient 渐变还能这么玩

    浏览器支持两种类型的渐变:线性渐变 (linear-gradient),径向渐变 (radial-gradient) 渐变在 CSS 中属于一种 Image 类型,可以结合 background-im ...

  7. Python 游戏之旅(Pygame)

    Pygame是跨平台Python模块,专为电子游戏设计,包含图像.声音.建立在SDL基础上,允许实时电子游戏研发而无需被低级语言(如机器语言和汇编语言)束缚.基于这样一个设想,所有需要的游戏功能和理念 ...

  8. ubuntu16.04 Docker默认存储路径修改

    Ubuntu 16.04 Docker默认存储路径修改

  9. hibernate框架(3)---持久化对象

    持久化对象 再讲持久化对象之前,我们先来理解有关session中get方法与 load方法区别: 简单总结: (1)如果你使用load方法,hibernate认为该id对应的对象(数据库记录)在数据库 ...

  10. Android--通过Application传递数据

    在整个Android程序中,有时需要保存某些全局的数据(如:用户信息),方便在程序的任何地方调用.在Activity之间数据传递中有一种比较使用的方式,就是全局对象,使用过J2EE的都应该知道Java ...