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的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度为 ...
随机推荐
- NAT详解:基本原理、穿越技术(P2P打洞)、端口老化等
这是一篇介绍NAT技术要点的精华文章,来自华3通信官方资料库,文中对NAT技术原理的介绍很全面也很权威,对网络应用的应用层开发人员而言有很高的参考价值. 学习交流 移动端即时通讯学习交流: 21589 ...
- 微信小程序开发用户授权登录
用wx.login获取登录凭证code <!--pages/user/index.wxml--> <view hidden='{{boolean}}'> <view wx ...
- Python学习笔记【第三篇】:if判断、while循环、for循环
如果某些条件满足,才能做某件事情,而不满足时不允许做,这就是所谓的判断 不仅生活中有,在软件开发中“判断”功能也经常会用到 if判断语句 if 要判断的条件: 条件成立 num = 50 if num ...
- 前端页面使用emoji
概述 最近在工作中遇到了移动端emoji的显示问题,于是查找了一些相关资料,试验了一番,把心得记录下来,供以后开发时参考,相信对其他人也有用. 参考资料: 为网站添加emoji表情的支持 思路 在页面 ...
- Mysql基本查询、视图、索引、触发器
基本查询 1.修改String sql="update smbms_user set userCode=?,userName=? where id=?"; 2.删除用户String ...
- c# 导入导出excel方法封装
在很多项目中,都会使用到文件的上传下载等,为了方便,封装了一个帮助类,每次直接拿过来使用就可以了,下面是封装的类和使用方法. using Common.AttributeHelper; using N ...
- js数组之sort排序的用法
sort排序 转载自:https://blog.csdn.net/idomyway/article/details/80544509 js中用方法sort()为数组排序.sort()方法有一个可选参数 ...
- MapReduce中的Join
一. MR中的join的两种方式: 1.reduce side join(面试题) reduce side join是一种最简单的join方式,其主要思想如下: 在map阶段,map函数同时读取两个文 ...
- 调度器简介,以及Linux的调度策略
进程是操作系统虚拟出来的概念,用来组织计算机中的任务.但随着进程被赋予越来越多的任务,进程好像有了真实的生命,它从诞生就随着CPU时间执行,直到最终消失.不过,进程的生命都得到了操作系统内核的关照.就 ...
- 记一次安装Ipython的流程
这是一个悲伤的安装ipython的过程. 写下来留个教训吧. 也是希望对博友一些帮助吧. 注: 我也写了一篇window下安装bpython的文章(个人感觉bpython要比ipython强大的多), ...