Magic Index 寻找数组中A[i]=i的位置(原题转自微信号待字闺中)
有一个有意思的题目叫做Magic Index:给定一个数组A,其中有一个位置被称为Magic Index,含义是:如果i是Magic Index,则A[i] = i。假设A中的元素递增有序、且不重复,请给出方法,找到这个Magic Index。更进一步,当A中允许有重复的元素,该怎么办呢?
一般情况下这种题目一看没有多复杂的时间复杂度,直接扫描一边数组就好了,O(n),当我们认识读题目的时候发现有个体检没有用到就是这个“数组元素递增有序,不重复”,这句话会不会给我们带来捷径呢,事实是可以的。通常在有序的数组中查找满足条件的元素,我们通常会想到二分法。这里不再啰嗦二分法的思想了。
那么,我们的题目能够利用上述的思想呢?我们来看一个具体的例子:
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相悖。所以,接下来,只能在右边进行查找。代码与二分查找也很像。
有重复元素的情况
如果数组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
-10 2 2 2 2 10 12
这个例子,当我们进行左半部分递归处理的时候,需要考虑的范围是[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
-10 2 2 2 9 10 12
此时,要在右半部分进行查找,范围一般是[5, 8]。但是,由于数组有序,后面的值,一定是大于等于A[mid]=9的。所以,有可能是Magic Index的最小Index是9,也就是说右边的递归,从max(mid+1,A[mid])开始查找,本题应该是从索引为9的位置开始。此例,就意味着,无需处理右边了。
Magic Index 寻找数组中A[i]=i的位置(原题转自微信号待字闺中)的更多相关文章
- 寻找数组中的第K大的元素,多种解法以及分析
遇到了一个很简单而有意思的问题,可以看出不同的算法策略对这个问题求解的优化过程.问题:寻找数组中的第K大的元素. 最简单的想法是直接进行排序,算法复杂度是O(N*logN).这么做很明显比较低效率,因 ...
- [经典算法题]寻找数组中第K大的数的方法总结
[经典算法题]寻找数组中第K大的数的方法总结 责任编辑:admin 日期:2012-11-26 字体:[大 中 小] 打印复制链接我要评论 今天看算法分析是,看到一个这样的问题,就是在一堆数据 ...
- 寻找数组中第K大数
1.寻找数组中的第二大数 using System; using System.Collections.Generic; using System.Linq; using System.Text; u ...
- Java实现 蓝桥杯 算法训练 寻找数组中最大值
算法训练 寻找数组中最大值 时间限制:1.0s 内存限制:512.0MB 提交此题 问题描述 对于给定整数数组a[],寻找其中最大值,并返回下标. 输入格式 整数数组a[],数组元素个数小于1等于10 ...
- C#中使用IndexOf()判断字符串在字符串数组中第一次出现的索引位置
] {"}; "; //判断字符串的前几位在另一个字符串数组中第一次出现的索引位置 index = Array.IndexOf(s, s1.Substring(, ));
- 交换数组中两个元素的位置,元素包括key和value 一维数组
/*author: yangyu@sina.cndescription: 交换数组中两个元素的位置,元素包括key和value,具体用法见下面的例子*/$arr = array(11=>'a', ...
- 寻找数组中第K频繁的元素
问题是:给你一个数组,求解出现次数第K多的元素.当然leetcode上的要求是算法复杂度不能大于O(N*logN). 首先这个问题我先是在leetcode上看到,当时想了两种做法,做到一半都觉得不是很 ...
- 窥探算法之美妙——寻找数组中最小的K个数&python中巧用最大堆
原文发表在我的博客主页,转载请注明出处 前言 不论是小算法或者大系统,堆一直是某种场景下程序员比较亲睐的数据结构,而在python中,由于数据结构的极其灵活性,list,tuple, dict在很多情 ...
- 2.10 用最少次数寻找数组中的最大值和最小值[find min max of array]
[本文链接] http://www.cnblogs.com/hellogiser/p/find-min-max-of-array.html [题目] 对于一个由N个整数组成的数组,需要比较多少次才能把 ...
随机推荐
- jdbc驱动jar导入eclipse
在使用JDBC编程时需要连接数据库,导入JAR包是必须的,导入其它的jar包方法同样如此,导入的方法是 打开eclipse 1.右击要导入jar包的项目,点properties 2.左边选择java ...
- Qt5.3.0的安装与测试
Qt5.3.0的安装与测试(交叉编译,用于arm,支持tslib触摸屏) 本次移植可以使用触摸屏. 首先下载源码包: http://download.qt.io/official_releases/q ...
- 个人对于css sprite的一点点见解
css sprite即CSS雪碧图又称CSS精灵.它存在的一个主要作用就是:减少了网页的http请求次数,从而大大的提高了页面的性能,节省时间和带宽. 例如 这样算下来.CSS sprite真的是个很 ...
- iOS_核心动画CALayer(一)
目 录: 一.核心动画简介 二.图层与视图之间的关系 三.CALayer的使用说明 四.CALayer的隐式动画属性 五.在CALayer上绘图 六.总结 一.核心动画简介 Core Anim ...
- java.sql.SQLException: Incorrect string value: '\xF0\x9F\x91\x88\xE6\x88...' for column 'content' at row 1
往MySQL插入数据时,报错如下 java.sql.SQLException: Incorrect at com.mysql.cj.jdbc.exceptions.SQLError.createSQL ...
- HIVE HSQL 基本操作命令
创建表: hive>create table tablename(id int,name string,password string); 创建一个名字为tablename的表,表的属性有int ...
- 先有Class还是先有Object?
先有Class还是先有Object? Java的对象模型中: 所有的类都是Class类的实例,Object是类,那么Object也是Class类的一个实例. 所有的类都最终继承自Object类,Cla ...
- C# XML对象序列化、反序列化 - PEPE YU
http://www.tuicool.com/articles/IjE7ban http://www.cnblogs.com/johnsmith/archive/2012/12/03/2799795. ...
- waitpid使用的一点问题
使用waipid的时候遇到了一个奇怪的问题,将情况简化后描述一下. 有关waitpid的基本介绍参见这里一下:http://www.cnblogs.com/mickole/p/3187770.html ...
- JavaScript -- Input Select 操作, 级联菜单
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...