一万个“无序”数查找两个重复数,在O(N)的基础上再快一点
原题见 莫贝特 的博客,意思是 1-1000组成的序列,再加入一个1-1000之间的数,然后将这1001个数打乱顺序。 问题:你现在拿到了这样一组数,请用最少的内存开销、最少的时间开销,找出那个重复的数。 由于最初没看清题意,以为是有序数列,于是想到了二分法。二分法是好方法,但是运用的前提条件搞错了,自然结果也就错了,受到 Zhao 首长的严肃批评。 但是本人对O(N)的时间复杂度仍然耿耿于怀,决定彻夜不明找出哪怕再快一点点的算法,下面我们来分析分析。 |
目前的算法是:(1001个数字的和)- (1000个数字的和)= (1001个数字的和)- n*(n+1)/2= 重复数字,求和需要1000次循环。
这个算法之所以能成立,是因为序列是由1-1000的连续数字组成的,因此,不管他们怎么排列,(1000个数字的和)都是从1加到1000。但是,如果这1000个数字不是连续的,比如是从1-100000中随机选出来的互不相同的1000个数,那么这个算法就不成立了,因为我们无法知道(1000个数字的和)到底是哪1000个数字。
既然现在给出的条件是1-1000的乱序,那么就可以利用连续这一特殊性来改进算法。
最简单的方法应该是:再开辟一个1000空间的数组 list2 ,将这1001个数字从第一个开始,依次放到 list2 中他的编号位置上
比如:
list2[list[0]-1]=list[0]
list2[list[1]-1]=list[1]
依次这样做下去,直到某个要保存的数字在 list2 对应的位置上已经存在,就找到了这个数字。
但是这次我看清要求了,不能开辟新的空间。
虽然不能开辟新的空间,思路却已经有了,就是利用连续性和索引的对应关系,具体算法描述如下:
1、取出第一个位置的数字:p1=list[0]
2、将第一个位置标记:list[0]=0
3、取出 p1 位置的数字:p2=list[p1]
4、将 p1 位置标记:list[p1]=0
5、取出 p2 位置的数字:p3=list[p2]
6、将 p2 位置标记:list[p2]=0
.............
依次做下去,直到下一个要找的位置被标记过了,数字就找到了。
原因是:那个重复的数字,最终要访问他自己的位置第二次,当他访问时,发现位置已经被上一个自己访问过了,他就知道自己不是唯一的了。
这种算法叫什么名字我也不知道,能不能叫漫游算法?
在最好的情况下,他的循环次数是 1,比如[1,1,....1000]
在最坏的情况下,他的循环次数是 1000,比如[1,2,3......1000,1000]
平均情况下,他的循环次数是 N/2,虽说数量级上仍然是 O(N)级别的,但是平均来说,仍然比前面的求和法快了一倍
下面给出代码,还是可爱的 Python :
# -*- coding: GBK -*-
import random
# 生成数列
arr_length=10001
list=range(1,arr_length)
#加入一个随机数
rnd=random.randrange(1,arr_length)
list.append(rnd)
print '\n重复数为:'+ str(rnd)
#打乱顺序
random.shuffle(list)
# 正式开始查找算法
count=0
idx=0
while (list[idx]!=0):
count=count +1
temp=list[idx]
list[idx]=0
idx=temp
print "找到:%d,循环 %d 次" % (temp,count)
多次运算结果如下图:
//==========================================
一万个“无序”数查找两个重复数,在O(N)的基础上再快一点相关推荐
- 一万个数查找两个重复数,快速二分查找法 O(logN)(转)
题目:1-1000放在含有1001个元素的数组中,只有唯一的一个元素值重复,其它均只出现一次.每个数组元素只能访问一次,设计一个算法,将它找出来:不用辅助存储空间,能否设计一个算法实现? 一.有序情况 ...
- js 实现查找两个数组中的不同项——基础积累
今天遇到一个需求,就是select的多选下拉,根据选中的值再进行相应的处理.比如当前选中了['山东','浙江','深圳']三项内容,现在去掉中间的深圳,我需要拿到去掉的是哪一项. 我想的方式就是: w ...
- 在一个数组中查找两个重复出现的数字
题目如下:现有一个数组长度为n+1,里面存放有1到n-2,顺序不定,其中有两个数字出现了两次,现在要找出那两个数字. 例子A={2, 3, 1, 4, 5, 2, 4}, 这个数组长度为7,存放了1到 ...
- 查找两个字符串a,b中的最长公共子串
查找两个字符串a,b中的最长公共子串 文章目录 查找两个字符串a,b中的最长公共子串 一.题目描述 二.代码 一.题目描述 题目描述: 查找两个字符串a,b中的最长公共子串.若有多个,输出在较短串中最 ...
- 阿里云峰会|阿里云数据中台重磅升级后拟扶持100万家企业数智化
6月9日,在2020阿里云线上峰会上,阿里巴巴集团副总裁.数据技术及产品部负责人朋新宇推出Quick Audience.Quick A+两款全新产品,并升级Dataphin和Quick BI两款现有产 ...
- 【Excel】乱序不同行数的两列数据对比匹配
1 情境 表格需求: 以上乱序不同行数的两个表格分别为总名单和签到表,需要在总名单中找到未签到人员. 表格特点: [表2:签到表] 为 [表1:总名单] 的子集: 两表顺序错乱: 不同姓名对应身份证号 ...
- 【iOS高级资深工程师面试篇】⑪、2022年,金九银十我为你准备了《iOS高级资深工程师面试知识总结》 算法部分 字符串反转-链表反转-有序数组组合-Hash算法-查找两个子视图的共同父视图
iOS高级资深工程师面试篇系列 - 已更新3篇 UI部分1/3 -UITableView-事件传递&视图响应 UI部分2/3 -图像显示原理-UI卡顿&掉帧 UI部分3/3 -UIVi ...
- LeetCode 图解 | 1214.查找两颗二分搜索树之和
点击上方蓝字设为星标 下面开始今天的学习- 今天分享的题目来源于 LeetCode 第 1214 号问题:查找两颗二分搜索树之和.(会员题 ) 题目描述 给出两棵二叉搜索树,请你从两棵树中各找出一个节 ...
- 阿里云峰会 | 阿里云数据中台 重磅升级后拟扶持100万家企业数智化
6月9日,在2020阿里云线上峰会上,阿里巴巴集团副总裁.数据技术及产品部负责人朋新宇推出Quick Audience.Quick A+两款全新产品,并升级Dataphin和Quick BI两款现有产 ...
最新文章
- 激光雷达数据到云cloud
- Spring Cloud Data Flow 中的 ETL
- 【刷题】BZOJ 2125 最短路
- Exchange server 2013(十四)WSUS部署及组策略设置(2)
- Android Studio、 补充知识以及主要组件
- css 矩形两边挖半圆
- 处理工行b2c上海机构问题反思
- vue通过链接显示服务器上的图片_图片网站该如何做SEO优化?详细讲解图片优化技巧...
- 比尔·盖茨退出微软公司董事会;苹果 WWDC、微软 Build 大会均改为线上举办;Rust 1.42.0 发布| 极客头条...
- CCNP精粹系列之十七--路由映射实战,博主推荐
- ensp配置access口_华为路由交换技术 | 虚拟局域网VLAN详解与配置
- Oracle查看表空间使用率
- JAVA基础语法——关键字
- 江苏省苏州市谷歌高清卫星地图下载
- 神舟战神换cpu教程_神舟战神做工如何?神舟战神K650D-A29拆机图解教程
- 学习在Unity中制作基础的节点编辑器
- 在idea中使用git详解
- python半圆代码_r或python中的半圆形色轮[闭合]
- Python爬虫抓取链家二手房数据
- linux桌面只运行浏览器,4个Linux桌面上的轻量级图像浏览器