待字闺中之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中,字段的类型很关键: 在索引的时候,如果字段第一次出现,会自动识别某个类型,这种规则之前已经讲过了. 那么如果一个字段已经存在了,并且设置为某个类型.再来一条数据,字段的数据不与 ...
随机推荐
- freeswitch 一些坑
1.You must install libopus-dev to build mod_opus. Stop. 确实已经安装libopus-dev后 将文件 usr/local/src/mod/cod ...
- 查看Linux系统信息命令
系统 # uname -a # 查看内核/操作系统/CPU信息 # head -n 1 /etc/issue # 查看操作系统版本 # cat /proc/cpuinfo # 查看CPU信息 # ho ...
- python--(爬虫-re模块)
python--(爬虫-re模块) re模块四大核心功能: 1.findall 查找所有,返回list import re lst = re.findall("m", " ...
- MVC、RPC、SOA、微服务架构之间的区别
MVC.RPC.SOA.微服务架构之间的区别 一.MVC架构 其实MVC架构就是一个单体架构. 代表技术:Struts2.springMVC.Spring.Mybatis 等等. 二.RPC架构 RP ...
- 题解 P1774 【最接近神的人_NOI导刊2010提高(02)】
这道题很明显是求逆序对. 所谓逆序对,就是逆序的数对. 譬如在下面这个数列中: 1 2 3 4 6 5 6 5就是一个逆序对. 求逆序对的方法比较多,常见的有归并排序和树状数组(线段树当然也行). 本 ...
- excel2013超链接进不去,提示“您的组织策略不允许...”
搜索regedit 然后找到HKEY_CURRENT_USER->Software->Classes->.html 右键修改或者双击修改数值数据为Htmlfile 关闭之后此窗口,关 ...
- Http请求和相应模式(B/S)(1)
B/S模式 服务器端的接受数据 :浏览器端 表单格式 <form></form> GET:请求方式, /index.html Web浏览器上的资源路径 uname=bjxt& ...
- java ee服务器/应用服务器的理解
42.由Apache.Sun 和其他一些公司及个人共同开发而成.由于有了Sun 的参与和支持,最新的Servlet 和JSP 规范总是能在Tomcat 中得到体现.43.可以这样认为,当在一台机器上配 ...
- ZOJ 3687
赤裸的带禁区的排列数,不过,难点在于如何用程序来写这个公式了.纠结了好久没想到,看了看别人的博客,用了DFS,实在妙极,比自己最初想用枚举的笨方法高明许多啊.\ http://blog.csdn.ne ...
- 玩转iOS开发 - Runloop 具体解释
Runloop 具体解释