待字闺中之Magic Index 分析
给定一个数组A,当中有一个位置被称为Magic Index,含义是:如果i是Magic Index。则A[i] = i。
如果A中的元素递增有序、且不反复,请给出方法,找到这个Magic
Index。更进一步。当A中同意有反复的元素,该怎么办呢?
没有反复元素的情况
一些同学在遇到这个题目的时候,往往会认为比較简单。扫描一遍,不就ok了么?O(n)的。非常easy呀。但是,大家要注意到,另一个条件没实用:A中的元素是有序递增的。
这个条件,并非放在这里迷惑大家的。而是有更大的作用的。
这个时候,该怎样想呢?O(n)不是最好的方法,更好的是什么呢?怎么利用数组有序呢?在有序的数组中查找一个满足特定元素的条件。我们一般会想到二分查找。 我们来回想一下二分查找,对于要查找的目标t,我们首先与数组中间的元素比較,假设t大于中间的元素,则在右半部分继续查找;假设t小于中间的元素,则在左半部分,继续查找。
那么。我们的题目可以利用上述的思想呢?我们来看一个详细的样例:
0 1 2 3 4 5 6
-10 -5 1 2 4 10 12
mid=3。A[mid] = 2,即A[mid] < mid。接下来,我们应该在哪一边查找呢?我们知道数组的元素是递增有序,且不反复的。也就是说,在A[mid]左边的元素,比A[mid]都要小。没有反复,意味着什么呢?每向左移动一位,至少减1。所以,在mid左边,不可能有一个i,A[i]=i的。假设有。依据前面的分析。我们知道A[mid] - A[i] >= mid - i, 假设A[i] = i。则,A[mid] >= mid, 这与事实A[mid] < mid相悖。所以,接下来,仅仅能在右边进行查找。
代码与二分查找也非常像。
详细代码例如以下:
int MagicIndex(vector<int>& data)
{
int begin = 0,end = data.size()-1;
while(begin <= end)
{
int mid = begin + ((end - begin) >> 1);
if(data[mid] > mid)end = mid -1;
else if(data[mid] < mid)begin = mid + 1;
else return mid;
}
return -1;
}
有反复元素的情况
假设数组A中,有反复元素,是什么情况呢?经过前面的分析。我们知道,是否有反复的主要区别在,数组的元素从右到左进行递减,每次不一定至少是1了。有可能是0了。
让我们直观的看一下影响吧。
0 1 2 3 4 5 6
-10 2 2 2 9 10 12
看上面的数组,相同A[mid] < mid。我们应该继续查右边么?显然,右边并不存在Magic Index。查找右边,就会找不到这种Magic Index。
此时,应该怎样处理呢?我们无法确定,Magic Index是在左边,还是在右边了。那就两边都递归进行处理吧。
在这里另一个小技巧,我们就是要分别递归处理[0, mid - 1]和[mid + 1, end](end是数组长度-1)么?我们看一个详细的样例:
0 1 2 3 4 5 6 7 8
-10 2 2 2 2 10 12 15 20
这个样例,当我们进行左半部分递归处理的时候。须要考虑的范围是[0, 3]。可实际上。我们仅仅须要考虑[0, 2]。原因是,数组元素在mid=4的左边的值都要小于或者等于A[mid]=2,所以最大的一个有可能是Magic Index的。就是index为A[mid]的情况。所以,这时右边的边界应该是min(mid - 1, A[mid])。
那么,右边的情况呢?例如以下样例:
0 1 2 3 4 5 6 7 8
-10 2 2 2 9 10 12 15 20
此时,要在右半部分进行查找。范围通常是[5, 8]。可是,因为数组有序,后面的值,一定是大于等于A[mid]=9的。
所以。有可能是Magic Index的最小Index是9,也就是说右边的递归。应该是从索引为9的位置開始。此例,就意味着,无需处理右边了。
详细代码例如以下:
int MagicIndexDup(vector<int>& data,int begin,int end)
{
if(begin > end)return -1;
int mid = begin + ((end - begin) >> 1);
if(data[mid] == mid)return mid;
int res = MagicIndexDup(data,begin,min(mid-1,data[mid]));//递归左边
if( res == -1)res = MagicIndexDup(data,max(mid+1,data[mid]),end);//递归右边
return res;
}
int MagicIndexDup(vector<int>& data)
{
return MagicIndexDup(data,0,data.size()-1);
}
待字闺中之Magic Index 分析的更多相关文章
- Magic Index 寻找数组中A[i]=i的位置(原题转自微信号待字闺中)
有一个有意思的题目叫做Magic Index:给定一个数组A,其中有一个位置被称为Magic Index,含义是:如果i是Magic Index,则A[i] = i.假设A中的元素递增有序.且不重复, ...
- 算法----Magic Index
给定一个数组 A,如果 某个下标 i, 满足 A[i] = i, 则 i 称为 Magic Index. 现在假设 A 中的元素是递增有序的.且不重复,找出 Magic Index. 更进一步,当数组 ...
- 数组Magic Index
Question A magic index in an array A[1...n-1] is defined to be an index such that A[i] = i. Given a ...
- [8.3] Magic Index
A magic index in an array A[0...n-1] is defined to be an index such that A[i] = i. Given a sorted ar ...
- [CareerCup] 9.3 Magic Index 魔法序号
9.3 A magic index in an array A[0.. .n-1] is defined to be an index such that A[i] = i. Given a sort ...
- 目标用户偏好指数Target Group Index分析
目标用户偏好指数Target Group Index分析 TGI指数,全称Target Group Index,可以反映目标群体在特定研究范围内强势或者弱势. TGI指数计算公式 = 目标群体中具有某 ...
- mongodb query index 分析
query 的过程及分析: query 是通过Query planner选择最有效的查询plan ,为一个query 被给予一个可用的索引,查询时 query optimizer(最优的查询条件选择器 ...
- The Aggregate Magic Algorithms
http://aggregate.org/MAGIC/ The Aggregate Magic Algorithms There are lots of people and places that ...
- ES系列六、ES字段类型及ES内置analyzer分析
一.背景知识 在Es中,字段的类型很关键: 在索引的时候,如果字段第一次出现,会自动识别某个类型,这种规则之前已经讲过了. 那么如果一个字段已经存在了,并且设置为某个类型.再来一条数据,字段的数据不与 ...
随机推荐
- cf掉分记——Avito Code Challenge 2018
再次作死的打了一次cf的修仙比赛感觉有点迷.. 还好掉的分不多(原本就太低没法掉了QAQ) 把会做的前三道水题记录在这.. A: Antipalindrome emmmm...直接暴力枚举 code: ...
- python3 继承与组合
什么叫继承? 所谓继承,就是class_A里面的功能从class_B中直接获取,从而节约了代码且使用方便. 什么叫组合? 除了继承,还有一种我们可以实现目的的方式,那就是组合,同样可以节约代码.只不过 ...
- vue文件目录结构
使用node和npm环境,很容易搭建起一个vue环境.搭建完成以后,项目基本结构,如下图所示: 1.build: bulid文件夹保存的是一些webpack的初始化配置 2.config: confi ...
- js 对象的创建方式和对象的区别
js一个有三种方法创建对象,这里做一个总结. 1.对象直接量 所谓对象直接量,可以看做是一副映射表,这个方法也是最直接的一个方法,个人比较建议, 1 2 3 4 5 6 7 8 9 10 11 12 ...
- IOS版本号被拒的经历
IOS版本号被拒的经历: 1,登陆方式依赖外部平台 由于我们的APP是仅仅用微博登陆.想做成类似meerkat类型的.也能各种消息都同步微博. 结果当然行不通,这个确实是不听好人言.网上多个人都说过这 ...
- 【BUG】android.content.res.Resources$NotFoundException: File res/drawable-xxhdpi/toolbar_line.png from
SafeGod在coolpad(4.0)上执行.登陆进去的设备列表界面遇到的问题.三星和索尼没有这个问题. 06-24 15:23:06.897: E/AndroidRuntime(12655): F ...
- 在GitHub上使用Hexo搭建静态博客
搭建静态博客须要一个前提是电脑上有安装git而且有github帐号,这个不懂能够看廖雪峰先生的git教程 1.下载nodejs.在官网上能够下载 2.使用git进入你新建的一个目录,输入命令 npm ...
- select … into outfile 备份恢复(load data)以及mysqldump时间对比
select … into outfile 'path' 备份 此种方式恢复速度非常快,比insert的插入速度要快的多,他跟有备份功能丰富的mysqldump不同的是,他只能备份表中的数据,并不能包 ...
- luogu 2308添加括号
添加括号 传送门 题目大意 现在要添上n-1对括号,加法运算依括号顺序进行,得到n-1个中间和,求出使中间和之和最小的添括号方法. 这道题其实是一个很简单的区间dp,中间和的意思是括号里面的和,也就是 ...
- 创建ios界面的三步骤
1.加载数据 (包括懒加载和字典转模型等) 2.搭建界面 (常见的有九宫格算法和for循环的嵌套等) 3.实现用户交互 (通常用按钮实现)