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的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度为 ...
随机推荐
- jenkins在windows服务器上执行含git push命令的脚本权限不足的解决方法
错误摘要 默认情况下执行脚本是没问题的,但是脚本中含有git push命令就无法执行了 用jenkins部署hexo博客时候遇到的,执行hexo d -g一直阻塞至Build was aborted, ...
- 微博第三方登录使用social_django实现显示登陆的用户名
首先修改social_soce源码,将用户信息添加进cookie 将其修改为: response = backend.strategy.redirect(url) payload = jwt ...
- Apache Commons FileUpload 实现文件上传
Commons FileUpload简介 Apache Commons是一个专注于可重用Java组件开发的 Apache 项目.Apache Commons项目由三个部分组成: 1.Commons P ...
- Redis之分布式锁
目录 一.加锁原因 二.原子操作 三.分布式锁 四.分布式锁常见问题 一.加锁原因 在一些比较高并发的业务场景,经常听到通过加锁的方法实现线程安全. 下面简单介绍一下 1.1 加锁方式 数据库锁 数据 ...
- 可以用py库: pyautogui (自动测试模块,模拟鼠标、键盘动作)来代替pyuserinput
PyAutoGUI 是一个人性化的跨平台 GUI 自动测试模块 pyUserInput模块安装前需要安装pywin32和pyHook模块.(想要装的看https://www.cnblogs.com/m ...
- 如何用chrome注册版权登记系统
版权登记系统的网址: http://apply.ccopyright.com.cn/goadatadic/registergetList.do 打开网站,一股古朴的气息扑面而来,嗯,一看就是IE时代的 ...
- [NewLife.XCode]事务处理(算准你的每一分钱)
NewLife.XCode是一个有10多年历史的开源数据中间件,支持nfx/netstandard,由新生命团队(2002~2019)开发完成并维护至今,以下简称XCode. 整个系列教程会大量结合示 ...
- 函数式编程之-F#类型系统
在深入到函数式编程思想之前,了解函数式独有的类型是非常有必要的.函数式类型跟OO语言中的数据结构截然不同,这也导致使用函数式编程语言来解决问题的思路跟OO的思路有明显的区别. 什么是类型?类型在编程语 ...
- vue-15-vuex-store的用法
vue-16-vuex 1, 介绍 对 vue 进行状态管理的, 集中存储所有组件的所有状态, 解决多个组件共享数据的问题. 即, 所有组件可以拿到同样的状态, 组件间共享数据 2, 在之前进行数据交 ...
- Spring Boot 系列 - WebSocket 简单使用
在实现消息推送的项目中往往需要WebSocket,以下简单讲解在Spring boot 中使用 WebSocket. 1.pom.xml 中引入 spring-boot-starter-websock ...