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个整数组成的数组,需要比较多少次才能把 ...
随机推荐
- C#托管代码 CLR
托管代码 是直接编译成机器码,而是编译成中间语言 IL,由 CLR 托管运行. 托管代码就是把底层的一些操作(如内存的读取,释放)全都封装起来了,把有关内存管理的操作全都由CLR来管理, C#使用垃圾 ...
- Android:日常学习笔记(8)———探究UI开发(3)
Android:日常学习笔记(8)———探究UI开发(3) 详解四种基本布局 前言 布局定义用户界面的视觉结构,如Activity或应用小部件的 UI.您可以通过两种方式声明布局: 在 XML 中声明 ...
- JavaScript:学习笔记(2)——基本概念与数据类型
JavaScript:学习笔记(2)——基本概念与数据类型 语法 1.区分大小写.Test 和 test 是完全不同的两个变量. 2.语句最好以分号结束,也就是说不以分号结束也可以. 变量 1.JS的 ...
- Python学习进程(5)Python语法
本节介绍Python的基本语法格式:缩进.条件和循环. (1)缩进: Python最具特色的是用缩进来标明成块的代码. >>> temp=4;x=4; >> ...
- java Excel导入导出工具类
本文章,导入导出依赖提前定义好的模板 package com.shareworx.yjwy.utils; import java.io.File; import java.io.FileInputSt ...
- Linux基本命令 文件搜索命令
1.文件搜索命令find ================================================================================== 命令名称 ...
- jstl-functions标签
比如需要再jstl中定义一个String类型的数组 <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl ...
- Linux环境下的图形系统和AMD R600显卡编程(2)——Framebuffer、DRM、EXA和Mesa简介
转:https://www.cnblogs.com/shoemaker/p/linux_graphics02.html 1. Framebuffer Framebuffer驱动提供基本的显示,fram ...
- @MarkFan 口语练习录音 20140415 [MDL演讲口语录音]
Hi,everybody! 今天是2014年4月14日, 现在是晚上十一点零柒分. 一本励志的书,一场振奋人心的演讲,一次推心置腹的谈话, 最多只是在你背后小推你一下,最终决定是否迈出前进的步伐, 以 ...
- Android系统--Binder系统具体框架分析(一)补充
Android系统--Binder系统具体框架分析(一)补充 补充:对Binder驱动分析一的代码补充,添加saygoobye和saygoodbye_to服务 test_server.h #ifnde ...