No.3 数组中重复的数字 (P39)
题目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)的更多相关文章
- 【Java】 剑指offer(1) 找出数组中重复的数字
本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 在一个长度为n的数组里的所有数字都在0到n-1的范围内.数组中某些数字 ...
- 《剑指offer》第三_一题(找出数组中重复的数字,可改变数组)
// 面试题3(一):找出数组中重复的数字 // 题目:在一个长度为n的数组里的所有数字都在0到n-1的范围内.数组中某些数字是重复的,但不知道有几个数字重复了, // 也不知道每个数字重复了几次.请 ...
- 剑指offer35题:第一个只出现一次的字符+剑指offer55题:字符流中第一个不重复的字符+剑指offer51题:数组中重复的数字
在看剑指offer的时候,感觉这三个题目很像,都是用哈希表可以解决,所以把这三个题整理出来,以供复习. 剑指offer35题:第一个只出现一次的字符 题目描述:在字符串中找出第一个只出现一次的字符.如 ...
- 剑指Offer(书):数组中重复的数字
题目:找出数组中重复的数字. 说明:在一个长度为n的数组里的所有数字都在0~n-1的范围内,数组中某些数字是重复的,但是不知道有几个数字重复了,也不知道每个数字重复了几次.请找出数组中任意一个重复的数 ...
- JavaScript去除数组中重复的数字
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 【剑指Offer】面试题03. 数组中重复的数字
题目 找出数组中重复的数字. 在一个长度为 n 的数组 nums 里的所有数字都在 0-n-1 的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次.请找出数组中任意 ...
- leetcode题库练习_数组中重复的数字
题目:数组中重复的数字 找出数组中重复的数字. 在一个长度为 n 的数组 nums 里的所有数字都在 0-n-1 的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次 ...
- 剑指offer数组中重复的数字
package 数组; /*在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的. 也不知道每个数字重复几次.请找出数组中任意一个重复的数字. ...
- 剑指offer二刷——数组专题——数组中重复的数字
题目描述 在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度为 ...
随机推荐
- attention 介绍
前言 这里学习的注意力模型是我在研究image caption过程中的出来的经验总结,其实这个注意力模型理解起来并不难,但是国内的博文写的都很不详细或说很不明确,我在看了 attention-mech ...
- Windows Server2012 搭建域错误“本地Administraor账户不需要密码”
标签:MSSQL/SQLServer/域控制器提升的先决条件验证失败/密码不符合要求 概述 在安装WindowsServer2012域控出现administrator账户密码不符合要求的错误,但是实际 ...
- 传统asp.net小心 async/await坑
最近在改老项目时,干了一件自以为很有成就感的事,心想 “项目都是同步方法,为啥不用异步方法呢?”,于是有了异步方法,类型下面的代码(当然是举例子说明啊) //更新某人名下公司名称 public Tas ...
- 【洛谷4172】 [WC2006]水管局长(LCT)
传送门 洛谷 BZOJ Solution 如果不需要动态的话,那就是一个裸的最小生成树上的最大边权对吧. 现在动态了的话,把这个过程反着来,就是加边对吧. 现在问题变成了怎么动态维护加边的最小生成树, ...
- JSP内置对象的使用(一)
JSP九大内置对象是:request.response.session.application.out.pagecontext.config.page.exception. JSP常用的内置对象是:o ...
- 数字(Number)类型(一)
多行语句 Python 通常是一行写完一条语句,但如果语句很长,我们可以使用反斜杠(\)来实现多行语句,例如: total = item_one + \ item_two + \ item_three ...
- 分布式事务之深入理解什么是2PC、3PC及TCC协议?
导读 在上一篇文章<[分布式事务]基于RocketMQ搭建生产级消息集群?>中给大家介绍了基于RocketMQ如何搭建生产级消息集群.因为本系列文章最终的目的是介绍基于RocketMQ的事 ...
- 【python35小工具】b站弹幕保存
后面有时间学习弹框,加个弹框 效果图: 原理: 原理简单不繁琐 1 根据设置的参数去post请求json参数 2 json提取出用户名和时间以及弹幕内容 (其中值得注意的时,页面默认会保存10个弹幕, ...
- Java Socket NIO详解(转)
java选择器(Selector)是用来干嘛的? 2009-01-12 22:21jsptdut | 分类:JAVA相关 | 浏览8901次 如题,不要贴api的,上面的写的我看不懂希望大家能给我个通 ...
- NewLife.Redis基础教程
X组件缓存架构以ICache接口为核心,包括MemoryCache.Redis和DbCache实现,支持FX和netstandard2.0!后续例程与使用说明均以Redis为例,各缓存实现类似. Re ...