算法----Magic Index
给定一个数组 A,如果 某个下标 i, 满足 A[i] = i, 则 i 称为 Magic Index。
现在假设 A 中的元素是递增有序的、且不重复,找出 Magic Index.
更进一步,当数组中有重复的元素呢??
分析:
首先题目不难。
最简单的当然是 扫描一遍数组,当然这个 O(N)的算法不是最优的。
进一步思考,如今数组是递增的,可否采用 二分搜索,从而加速到 O(lgN)?
if a[mid] == mid, return mid;
if a[mid] < mid, search in range[mid+1, right];
Why? 左半部分一定不会有 Magic index。 反证法: 假如左半部分存在一个 K 是Magic index, 则 a[K] = K.
由于没有重复的元素,所以数组元素从左到右递增的时候,每次增加至少是 1。
从而有 a[mid] > a[K] + mid-K > K + mid - K = mid, 得到矛盾。
if a[mid] > mid, search in range[left, mid-1];
考虑下面的一个例子:
index: 0 1 2 3 4 5 6
value: -10 -5 1 2 4 10 12
a[mid] = 2 < mid = 3, 继续在右半部分找即可,。
二、假设存在重复的元素
由于存在重复的元素,所以数组元素从左到右递增的时候,每次增加不一定大于1了, 有可能是 0。
二分搜索不再使用。每次都必须对 左,右两半都进行搜索。
但是这里还是有一个小 trick,
如果 a[mid] < mid, 左边仅需要搜索 (left, a[mid]), 右边还是搜索 (mid+1, right).
如果 a[mid] > mid, 右边仅需要搜索 (a[mid], right), 左边还是搜索 (left, mid-1).
拿个例子来说明:
index: 0 1 2 3 4 5 6
value: -10 1 1 1 6 10 12
mid = 1 < a[mid] = 3
// copyright @ L.J.SHOU Feb.22, 2014
// magic index
#include <iostream>
using namespace std; // if found, return index;
// if not found, return -1;
int MagicIndex(int A[], int left, int right)
{
int index(-1); if(left <= right)
{
int mid = left + ((right - left) >> 1); if(A[mid] == mid) return mid;
else if(A[mid] < mid){
index = MagicIndex(A, left, A[mid]);
if(index != -1) return index; index = MagicIndex(A, mid+1, right);
if(index != -1) return index;
}
else{
index = MagicIndex(A, left, mid-1);
if(index != -1) return index; index = MagicIndex(A, A[mid], right);
if(index != -1) return index;
}
} return -1;
}
算法----Magic Index的更多相关文章
- [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 ...
- [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 ...
- 数组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 ...
- Magic Index 寻找数组中A[i]=i的位置(原题转自微信号待字闺中)
有一个有意思的题目叫做Magic Index:给定一个数组A,其中有一个位置被称为Magic Index,含义是:如果i是Magic Index,则A[i] = i.假设A中的元素递增有序.且不重复, ...
- 待字闺中之Magic Index 分析
给定一个数组A,当中有一个位置被称为Magic Index,含义是:如果i是Magic Index.则A[i] = i. 如果A中的元素递增有序.且不反复,请给出方法,找到这个Magic Index. ...
- The Aggregate Magic Algorithms
http://aggregate.org/MAGIC/ The Aggregate Magic Algorithms There are lots of people and places that ...
- 字符串匹配(二)----KMP算法
什么是KMP算法: KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt同时发现,因此人们称它为克努特——莫里斯——普拉特操作(简称KMP算法).KMP ...
- MySQL联接查询算法(NLJ、BNL、BKA、HashJoin)
一.联接过程介绍 为了后面一些测试案例,我们事先创建了两张表,表数据如下: 1 2 3 4 CREATE TABLE t1 (m1 int, n1 char(1)); CREATE TABLE t ...
- BF算法和KMP算法 python实现
BF算法 def Index(s1,s2,pos = 0): """ BF算法 """ i = pos j = 0 while(i < ...
随机推荐
- XPath的语法
XPath 是XML的查询语言,和SQL的角色很类似.以下面XML为例,介绍XPath 的语法. <?xml version="1.0" encoding="ISO ...
- 为设计师准备的 20 个新的免费 PSD 模板
设计师们每天的工作经常要用到各种模板,本文推荐 20 个新的免费 PSD 模板,可节省设计时间. Blueprint Notice PSD Wooden Drawer Icon Minimal Clo ...
- 笔记6:winfrom连接sql server 进行数据交换
今天的作业是用winfrom窗体做一个留言板,如图: 要求和数据库有查询和添加功能.下拉框里的值是直接获取数据库中的值 一.连接数据库,获取表中数据 //创建一个存数据的表 DataTable tab ...
- HDUOJ------3336 Count the string(kmp)
D - Count the string Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64 ...
- jq 中each的用法
jQuery的each方法的几种常用的用法 each()方法能使DOM循环结构简洁,可遍历一维数组.多维数组.DOM, JSON 等等. var arr = [ "one", &q ...
- BZOJ3308 九月的咖啡店
Orz PoPoQQQ 话说这题还有要注意的地方... 就是...不能加SLF优化,千万不能加 n = 40000,不加本机跑出来2sec,加了跑出来40sec...[给跪了 /*********** ...
- 使用ContentObserve监听用户发出的短信
import android.net.Uri;import android.os.Bundle;import android.os.Handler;import android.app.Activit ...
- [css]邮件的写法
<style type="text/css"> /* Client-specific Styles */ #outlook a{paddin ...
- DP 剪枝
DP其实也是和搜索一样可以有剪枝的,昨晚看到一个超级好的DP剪枝题:(HDU - 5009) N段东东,要染色,每次给一个区间染色需要的花费为 该区间颜色总数的平方. 每一段只能被染一次色.求 最 ...
- 一模 (5) day2
第一题: 题目大意:使得 x^x 达到或超过 n 位数字的最小正整数 x 是多少? n<=2*10^9 解题过程: 1.以前看到过这题了,一个数x的位数=(int)lg(x)+1 换一下底就是 ...