美文网首页
数组-二分查找

数组-二分查找

作者: Summer舒舒 | 来源:发表于2017-11-02 16:25 被阅读21次

一、LintCode链接

http://www.lintcode.com/zh-cn/problem/first-position-of-target/

二、问题描述

给定一个排序的整数数组(升序)和一个要查找的整数target,用O(logn)的时间查找到target第一次出现的下标(从0开始),如果target不存在于数组中,返回-1。

三、关键点分析

  • 升序数组
  • 数据量
  • n0<=n1<=n2<=....,数据可能连续相等
  • 第一次出现的下标

四、解决思路(Java)

1.数据量不大,递归法和非递归法
递归法
 public int binarySearch(int[] nums, int fromIndex, int toIndex, int target) {
        if (nums == null || nums.length <= 0
             || fromIndex > toIndex || fromIndex < 0 || toIndex >= nums.length) {
            return -1;
        }

        int midIndex = (fromIndex + toIndex) >>> 1;
        int midValue = nums[midIndex];

        if (midValue < target) {
            return binarySearch(nums, midIndex + 1, toIndex, target);
        } else if (midValue > target) {
            return binarySearch(nums, fromIndex, midIndex - 1, target);
        } else {
            int beforeIndex = binarySearch(nums, fromIndex, midIndex - 1, target);
            return beforeIndex > 0 ? beforeIndex : midIndex;
        }
    }
非递归法
 public int binarySearch(int[] nums, int target) {
        if (nums == null || nums.length <= 0) {
            return -1;
        }

        int resultIndex = -1;

        int fromIndex = 0;
        int toIndex = nums.length - 1;

        while (fromIndex <= toIndex) {
            int midIndex = (fromIndex + toIndex) >>> 1;
            int midValue = nums[midIndex];

            if (midValue < target) {
                fromIndex = midIndex + 1;
            } else if (midValue > target) {
                toIndex = midIndex - 1;
            } else {
                resultIndex = midIndex;
                toIndex = midIndex - 1;
            }
        }
        return resultIndex;
    }
2.数据量大,借助树或堆和Quick Select算法(TODO)

五、相关

1.源码中的二分查找
    SparseArray.get方法:
    public E get(int key, E valueIfKeyNotFound) {
        int i = ContainerHelpers.binarySearch(mKeys, mSize, key);

        if (i < 0 || mValues[i] == DELETED) {
            return valueIfKeyNotFound;
        } else {
            return (E) mValues[i];
        }
    }

    ContainerHelpers.binarySearch()方法:
    static int binarySearch(int[] array, int size, int value) {
        int lo = 0;
        int hi = size - 1;

        while (lo <= hi) {
            final int mid = (lo + hi) >>> 1;
            final int midVal = array[mid];

            if (midVal < value) {
                lo = mid + 1;
            } else if (midVal > value) {
                hi = mid - 1;
            } else {
                return mid;  // value found //从这里可以看出只要找到就返回,不考虑数据连续相等的情况
            }
        }
        return ~lo;  // value not present
    }
2.链接

维基-二分搜索

相关文章

  • 二分法查找

    二分法查找的前提是数组必须排序!!!二分法查找的前提是数组必须排序!!!二分法查找的前提是数组必须排序!!!二分法...

  • 查找

    顺序查找 二分查找 插值查找 查找子数组最大和

  • 二分查找及其扩展

    在有序数组中,二分查找是效率较高的查找算法。二分查找一般有递归和迭代 对有序数组查找指定数字在数组中出现的次数//...

  • day13

    查找算法 顺序查找 二分查找 差值查找 斐波那契查找 二分查找 前提数组必须是有序的。 升级 Interpolat...

  • 循环数组的二分查找--Java实现

    与普通二分查找的不同: 以上的查找对象为循环数组,而普通二分查找的对象为有序的普通数组; 正因为是循环数组,取中进...

  • BinarySearch

    前提 必须是有序数组。 思路 无重复数组二分查找 有重复数组二分查找 思路 1.退出条件leftIndx>righ...

  • Java数据结构和算法(有序数组和二分查找)

    一、概述 有序数组中常常用到二分查找,能提高查找的速度。今天,我们用顺序查找和二分查找实现数组的增删改查。 二、有...

  • 4-1 LC:二分查找

    有序数组的二分查找

  • 二分搜索算法 Go

    说明 二分查找的数组必须是有序的,二分查找的优点是查找操作仅需要O(lgN)时间。 逻辑 首先传入的数组必须是有序...

  • 二分查找法

    使用二分查找的前提是,查找的数组顺序必须是有序的。 二分查找又称折半查找,通过定义有序数组(左小右大)的首元素的索...

网友评论

      本文标题:数组-二分查找

      本文链接:https://www.haomeiwen.com/subject/wcgopxtx.html