美文网首页
二分查找的4种变体

二分查找的4种变体

作者: Jason_Shu | 来源:发表于2019-03-16 16:16 被阅读0次

在基本的二分查找法中,我们规定给定数组是不重复且有序的(一般为升序),这几个变体的规则有些变化,仍然是升序元素,但是可以有重复元素。

变体问题:
(1)查找第一个值等给定值的元素
(2)查找最后一个值等于给定值的元素
(3)查找第一个值大于等于给定值的元素
(4)查找最后一个值小于等于给定值的元素

接下来我们就来分析一下。

(1)查找第一个值等给定值的元素
我们要找给定值,核心算法还是二分查找,但是有了具体查找条件,「第一个值等给定值的元素」,怎么才算呢?在循环中,如果我们找到的等于给定值的值,而且这个值「位于整个数组的第一个位置或者它前面那个元素小于给定值」,那么就是我们要找的。这里大家可以体会一下这个查找条件。

代码:

// 查找第一个值等于给定值的元素
function find(arr, target) {
    let left = 0;
    let right = arr.length - 1;
    let mid;

    while(left <= right) {
        mid = Math.floor((left + right) / 2);
        if(arr[mid] > target) {
            right = mid - 1;
        } else {
            if(arr[mid] < target) {
                left = mid + 1;
            } else {
                // 剩下都是相等的情况,在这个大条件下我们加以约束
                // 如果当前元素是「处于数组第一个位置」或者「它前一个元素的值不等于给定值」,就符合要求
                if(mid === 0 || arr[mid - 1] !== target) {
                    return mid;
                } else {
                    // 不是第一个就向前找
                    right = mid -1;
                }
            }
        }
    }
    return -1;
}

let arr = [1,3,5,7,8,8,8,10];

console.log(find(arr, 8)) // 4

(2)查找最后一个值等于给定值的元素
在(1)的基础上稍微改变下判断条件,如果当前值「处于数组的最后一个」或者「当前值后一个值不等于给定值」即可。

代码:

// 查找最后一个值等于给定值的元素
function find(arr, target) {
    let left = 0;
    let right = arr.length - 1;
    let mid;

    while(left <= right) {
        mid = Math.floor((left + right) / 2);
        if(arr[mid] > target) {
            right = mid - 1;
        } else {
            if(arr[mid] < target) {
                left = mid + 1;
            } else {
                // 剩下都是相等的情况,在这个大条件下我们加以约束
                // 如果当前元素是「处于数组最后一个位置」或者「它后一个元素的值不等于给定值」,就符合要求
                if(mid === arr.length - 1 || arr[mid + 1] !== target) {
                    return mid;
                } else {
                    // 不是第一个就向后找
                    left = mid + 1;
                }
            }
        }
    }
    return -1;
}

let arr = [1,3,5,7,8,8,8,10];

console.log(find(arr, 8))  // 6

(3)查找第一个值大于等于给定值的元素
主体还是运用二分法,先找到「大于等于给定值的元素」区域,然后判断条件是:如果当前元素是「数组第一个」或者「它前面一个元素小于给定值」。

代码:

// 查找第一个值大于等于给定值的元素
function find(arr, target) {
    let left = 0;
    let right = arr.length - 1;
    let mid;

    while(left <= right) {
        mid = Math.floor(( left + right) / 2);
        if(arr[mid] >= target) {
            // 这里的情况就是「值大于等于给定值」的元素
            // 判断条件是:如果当前元素是「数组第一个」或者「它前面一个元素小于给定值」
            if(mid === 0 || arr[mid - 1] < target) {
                return mid;
            } else {
                // 如果不是第一个,则向前查找
                right = mid - 1;
            }
        } else {
            left = mid + 1;
        }
    }
}

let arr = [1,3,5,7,8,8,8,10];

console.log(find(arr, 6)) // 3

(4)查找最后一个值小于等于给定值的元素
基于(3),先找到「值小于等于给定值的元素」的区域,然后判断条件是:当前元素「处于数组的最后一个位置」或者「它后一个元素的值大于给定值」即可。

代码:

// 查找最后一个值小于等于给定值的元素
function find(arr, target) {
    let left = 0;
    let right = arr.length - 1;
    let mid;

    while(left <= right) {
        mid = Math.floor(( left + right) / 2);
        if(arr[mid] <= target) {
            // 这里的情况就是「值小于等于给定值」的元素
            // 判断条件是:如果当前元素是「数组最后一个」或者「它后面一个元素大于给定值」
            if(mid === arr.length - 1 || arr[mid + 1] > target) {
                return mid;
            } else {
                // 如果不是最后一个,则向后查找
                left = mid + 1;
            }
        } else {
            right = mid - 1;
        }
    }
}

let arr = [1,3,5,7,8,8,8,10];

console.log(find(arr, 7)) // 3

相关文章

  • 二分查找&变体

    二分查找其实占用的内存比较少,但是如果是寻找给定值的数据时,二分查找虽然占用内存小,但是用散列表或者二叉搜索树代替...

  • 二分查找(变体)

    今天写4种二分查找的变体分别是查找第一个值等于给定值的元素查找最后一个值等于给定值的元素查找第一个值大于等于给定值...

  • 二分查找的变体

    二分查找在已经排序好的数组中寻找某个值。它是最常见的O(lgn)时间复杂度算法。 标准写法 大学教科书上只会给出一...

  • 【算法打卡60天】Day14二分查找(下):如何快速定位IP对应

    学习内容:四种常见的二分查找变形问题1.变体一:查找第一个值等于给定值的元素2.变体二:查找最后一个值等于给定值的...

  • 二分查找以及变体

    标准二分查找 使用场景 排序的数组(排序,且支持随机读取) 不大不小的数据, 大了的话,数组太大,木有那么大的连续...

  • 二分查找的几种变体

    在一个有序数组中查找某个元素,采用二分查找是非常高效的,其查找只需要 O(logn) 的时间复杂度就可以了。如果数...

  • 二分查找(变体)代码框架

    1.说明 前面介绍了二分查找代码框架[https://www.jianshu.com/p/6423f7367615...

  • 二分查找的4种变体

    在基本的二分查找法中,我们规定给定数组是不重复且有序的(一般为升序),这几个变体的规则有些变化,仍然是升序元素,但...

  • 二分查找

    使用场景:下标随机访问元素的顺序表,有序,数据量适中(过小顺序查找,过大连续内存不够)二分法变体:查找第一个给定值元素。

  • 数据结构和算法--二分查找

    二分查找 二分查找的思想 二分查找(Binary Search)算法,也叫折半查找算法。 二分查找针对的是一个有序...

网友评论

      本文标题:二分查找的4种变体

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