原题见 莫贝特 的博客,意思是 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 :

#!/usr/bin/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)的基础上再快一点相关推荐

  1. 一万个数查找两个重复数,快速二分查找法 O(logN)(转)

    题目:1-1000放在含有1001个元素的数组中,只有唯一的一个元素值重复,其它均只出现一次.每个数组元素只能访问一次,设计一个算法,将它找出来:不用辅助存储空间,能否设计一个算法实现? 一.有序情况 ...

  2. js 实现查找两个数组中的不同项——基础积累

    今天遇到一个需求,就是select的多选下拉,根据选中的值再进行相应的处理.比如当前选中了['山东','浙江','深圳']三项内容,现在去掉中间的深圳,我需要拿到去掉的是哪一项. 我想的方式就是: w ...

  3. 在一个数组中查找两个重复出现的数字

    题目如下:现有一个数组长度为n+1,里面存放有1到n-2,顺序不定,其中有两个数字出现了两次,现在要找出那两个数字. 例子A={2, 3, 1, 4, 5, 2, 4}, 这个数组长度为7,存放了1到 ...

  4. 查找两个字符串a,b中的最长公共子串

    查找两个字符串a,b中的最长公共子串 文章目录 查找两个字符串a,b中的最长公共子串 一.题目描述 二.代码 一.题目描述 题目描述: 查找两个字符串a,b中的最长公共子串.若有多个,输出在较短串中最 ...

  5. 阿里云峰会|阿里云数据中台重磅升级后拟扶持100万家企业数智化

    6月9日,在2020阿里云线上峰会上,阿里巴巴集团副总裁.数据技术及产品部负责人朋新宇推出Quick Audience.Quick A+两款全新产品,并升级Dataphin和Quick BI两款现有产 ...

  6. 【Excel】乱序不同行数的两列数据对比匹配

    1 情境 表格需求: 以上乱序不同行数的两个表格分别为总名单和签到表,需要在总名单中找到未签到人员. 表格特点: [表2:签到表] 为 [表1:总名单] 的子集: 两表顺序错乱: 不同姓名对应身份证号 ...

  7. 【iOS高级资深工程师面试篇】⑪、2022年,金九银十我为你准备了《iOS高级资深工程师面试知识总结》 算法部分 字符串反转-链表反转-有序数组组合-Hash算法-查找两个子视图的共同父视图

    iOS高级资深工程师面试篇系列 - 已更新3篇 UI部分1/3 -UITableView-事件传递&视图响应 UI部分2/3 -图像显示原理-UI卡顿&掉帧 UI部分3/3 -UIVi ...

  8. LeetCode 图解 | 1214.查找两颗二分搜索树之和

    点击上方蓝字设为星标 下面开始今天的学习- 今天分享的题目来源于 LeetCode 第 1214 号问题:查找两颗二分搜索树之和.(会员题 ) 题目描述 给出两棵二叉搜索树,请你从两棵树中各找出一个节 ...

  9. 阿里云峰会 | 阿里云数据中台 重磅升级后拟扶持100万家企业数智化

    6月9日,在2020阿里云线上峰会上,阿里巴巴集团副总裁.数据技术及产品部负责人朋新宇推出Quick Audience.Quick A+两款全新产品,并升级Dataphin和Quick BI两款现有产 ...

最新文章

  1. 激光雷达数据到云cloud
  2. Spring Cloud Data Flow 中的 ETL
  3. 【刷题】BZOJ 2125 最短路
  4. Exchange server 2013(十四)WSUS部署及组策略设置(2)
  5. Android Studio、 补充知识以及主要组件
  6. css 矩形两边挖半圆
  7. 处理工行b2c上海机构问题反思
  8. vue通过链接显示服务器上的图片_图片网站该如何做SEO优化?详细讲解图片优化技巧...
  9. 比尔·盖茨退出微软公司董事会;苹果 WWDC、微软 Build 大会均改为线上举办;Rust 1.42.0 发布| 极客头条...
  10. CCNP精粹系列之十七--路由映射实战,博主推荐
  11. ensp配置access口_华为路由交换技术 | 虚拟局域网VLAN详解与配置
  12. Oracle查看表空间使用率
  13. JAVA基础语法——关键字
  14. 江苏省苏州市谷歌高清卫星地图下载
  15. 神舟战神换cpu教程_神舟战神做工如何?神舟战神K650D-A29拆机图解教程
  16. 学习在Unity中制作基础的节点编辑器
  17. 在idea中使用git详解
  18. python半圆代码_r或python中的半圆形色轮[闭合]
  19. Python爬虫抓取链家二手房数据
  20. linux桌面只运行浏览器,4个Linux桌面上的轻量级图像浏览器

热门文章

  1. Android6.0权限适配及兼容库的实现
  2. windows7下修改hosts文件无效解决办法(转)
  3. 金笛JDMail邮件服务器帮你应付电子邮件归档危机
  4. 使用 ExpandableListView 实现折叠ListView
  5. 《Ray Tracing in One Weekend》——Chapter 4: Adding a sphere
  6. 车联网中如何应用大数据
  7. 如何选择大数据分析软件
  8. 大数据分析常见的几种方法
  9. 哪些因素影响大数据的发展
  10. Scala学习(二、控制结构)