原题戳我

题目

Description

Given a big sorted array with positive integers sorted by ascending order. The array is so big so that you can not get the length of the whole array directly, and you can only access the kth number by ArrayReader.get(k) (or ArrayReader->get(k) for C++). Find the first index of a target number. Your algorithm should be in O(log k), where k is the first index of the target number.

Return -1, if the number doesn't exist in the array.

Notice:

If you accessed an inaccessible index (outside of the array), ArrayReader.get will return 2147483647.

Example

  • Given [1, 3, 6, 9, 21, ...], and target = 3, return 1.
  • Given [1, 3, 6, 9, 21, ...], and target = 4, return -1.

Challenge

O(log k), k is the first index of the given target number.

Tags

Sorted Array Binary Search

分析

这道题我是看题解才做出来的,思路非常好,有两个重点:

  1. 可以O(logk)的时间缩小二分法的范围
  2. 从而,可以将二分的最坏时间优化到O(logk)

第二点无需证明,下面讲解第一点。

以O(logk)的时间缩小二分法的范围

如果从0遍历到k,那么明显时间复杂度为O(k),超过了了O(logk)。

要记得,我们的目的是确定一个数组的上界r,使O(r)=O(k),继而在这段数组上进行二分查找,复杂度为O(logk)。因此,我们只需要将在O(logk)的时间内找到该r。

r的要求如下:

  1. 满足O(r)=O(k)
  2. 计算r的时间为O(logk)

即,寻找一个运算,进行O(logk)次,结果为O(k)。于是想到了乘幂

2 ** O(logk) = O(k)

代码如下:

    private int[] computeRange(ArrayReader reader, int target){
int r = 1;
while (reader.get(r) < target) {
r <<= 1;
} int l = r >> 1;
while (r >= l && reader.get(r) == 2147483647) {
r--;
}
if (r < l) {
return null;
} return new int[]{l, r};
}

完整代码

/**
* Definition of ArrayReader:
*
* class ArrayReader {
* // get the number at index, return -1 if index is less than zero.
* public int get(int index);
* }
*/
public class Solution {
/**
* @param reader: An instance of ArrayReader.
* @param target: An integer
* @return : An integer which is the index of the target number
*/
public int searchBigSortedArray(ArrayReader reader, int target) {
// write your code here
if (reader == null) {
return -1;
} if (reader.get(0) > target) {
return -1;
} int[] range = computeRange(reader, target);
if (range == null) {
return -1;
} int k = bsearchLowerBound(reader, range[0], range[1], target);
if (reader.get(k) != target) {
return -1;
} return k;
} private int[] computeRange(ArrayReader reader, int target){
int r = 1;
while (reader.get(r) < target) {
r <<= 1;
} int l = r >> 1;
while (r >= l && reader.get(r) == 2147483647) {
r--;
}
if (r < l) {
return null;
} return new int[]{l, r};
} private int bsearchLowerBound(ArrayReader reader, int l, int r, int v) {
while (l < r) {
int m = l + (r - l) / 2;
if (reader.get(m) >= v) {
r = m;
} else {
l = m + 1;
}
}
return l;
}
}

本文链接:【刷题】Search in a Big Sorted Array

作者:猴子007

出处:https://monkeysayhi.github.io

本文基于 知识共享署名-相同方式共享 4.0 国际许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名及链接。

【刷题】Search in a Big Sorted Array的更多相关文章

  1. LeetCode 新题: Find Minimum in Rotated Sorted Array 解题报告-二分法模板解法

    Find Minimum in Rotated Sorted Array Question Solution Suppose a sorted array is rotated at some piv ...

  2. LeetCode专题-Python实现之第26题:Remove Duplicates from Sorted Array

    导航页-LeetCode专题-Python实现 相关代码已经上传到github:https://github.com/exploitht/leetcode-python 文中代码为了不动官网提供的初始 ...

  3. LeetCode 新题: Find Minimum in Rotated Sorted Array II 解题报告-二分法模板解法

    Find Minimum in Rotated Sorted Array II Follow up for "Find Minimum in Rotated Sorted Array&quo ...

  4. lintcode 447 Search in a Big Sorted Array

    Given a big sorted array with positive integers sorted by ascending order. The array is so big so th ...

  5. 算法题丨Remove Duplicates from Sorted Array II

    描述 Follow up for "Remove Duplicates": What if duplicates are allowed at most twice? 示例 Giv ...

  6. 算法题丨Remove Duplicates from Sorted Array

    描述 Given a sorted array, remove the duplicates in-place such that each element appear only once and ...

  7. 【LeetCode每天一题】Remove Duplicates from Sorted Array II(移除有序数组中重复的两次以上的数字)

    Given a sorted array nums, remove the duplicates in-place such that duplicates appeared at most twic ...

  8. leetCode练题——26. Remove Duplicates from Sorted Array

    1.题目 26. Remove Duplicates from Sorted Array--Easy Given a sorted array nums, remove the duplicates  ...

  9. 【leetcode刷题笔记】Merge k Sorted Lists

    Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 题 ...

随机推荐

  1. TClientDataSet的FileName属性

    读取cds文件数据. FileName一定要在设计时输入,否则程序运行时,不会自动读取cds文件. 因为FORM创建时,数据集组件也相应创建,如果是在运行时 设置FileName,那么是在数据集组件创 ...

  2. 《Python》内置方法进阶和常用模块

    一:__new__ 在__init__之前,实例化对象的第一步是__new__创建了一个空间 class Foo: def __init__(self): # 初始化方法 print('执行了init ...

  3. Swift网络封装库Moya中文手册之Providers

    Providers 使用Moya,你可以通过一个 MoyaProvider 的实例发送所有网络请求,通过枚举来指定你要访问的具体API.在配置你的 Endpoint 之后,你差不多就做好了基础配置: ...

  4. 《JAVA----day01和day02》

    1,(在有符号的情况下)若一个二进制数都是1,则对应的十进制数是-1 2,在定义数值类型时,若无特别说明,整数默认:int  小数默认:double 在内存中 占字节数 取值范围 (1)byte:1个 ...

  5. PostgreSQL数据库创建只读用户总结

    好久没有弄,有点忘了,今天有客户问这个问题,发现几个SQL还解决不了,于是总结一下: --以超级用户登录数据库,创建用户: postgres=# create user test_read_only ...

  6. Ubuntu:火狐浏览器加速下载(Flashgot+Aria2+Uget)

    火狐浏览器加速下载 应用到的程序 Aria2 Uget firefox插件Flashgot 1.下载Uget sudo apt-get install uget 2. 下载Aria2 sudo apt ...

  7. vue 登录验证引擎

    1.router配置: 路由元信息 const router = new VueRouter({ routes: [ { path: '/foo', component: Foo, children: ...

  8. Windows Security Login

    /********************************************************************************* * Windows Securit ...

  9. chapter02 朴素贝叶斯分类器对新闻文本数据进行类型预测

    基本数学假设:各个维度上的特征被分类的条件概率之间是相互独立的.所以在特征关联性较强的分类任务上的性能表现不佳. #coding=utf8 # 从sklearn.datasets里导入新闻数据抓取器f ...

  10. 51Nod - 1001:数组中和等于K的数对

    基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题 给出一个整数K和一个无序数组A,A的元素为N个互不相同的整数,找出数组A中所有和等于K的数对.例如K = 8,数组A: ...