二分查找(Binary Search)的几种变种形式

二分查找的几种变种形式

二分查找是大家经常用而且也比较简单的一种算法,查找的时间复杂度为O(logn)。wiki上的定义为:

是一種在有序陣列中尋找某一特定元素的搜尋演算法

搜尋過程從陣列的中間元素開始,如果中間元素正好是要尋找的元素,則搜尋過程結束;如果某一特定元素大於或者小於中間元素,則在陣列大於或小於中間元素的那一半中尋找,而且跟開始一樣從中間元素開始比較。如果在某一步驟陣列為空,則代表找不到。這種搜尋演算法每一次比較都使搜尋範圍縮小一半。

简单的二分查找算法相信大家都会写,但是有时候经常会遇到一些变种形式,会让人头痛。

第一种:数组中没有重复元素,找到该元素返回该元素的下标,否则返回该元素的插入位置。

非递归写法:

public int binarySearch(int[] nums, int target) {
    int lo = 0;
    int hi = nums.length - 1;
    while (lo <= hi) {
        int mid = lo + (hi - lo) / 2;
        if (target < nums[mid]) hi = mid - 1;
        else if (nums[mid] < target) lo = mid + 1;
        else return mid;
    }
    return low;
}

递归写法:

 public int binarySearch(int[] nums, int target, int lo, int hi) {
    if (lo > hi) return lo;
    int mid = lo + (hi - lo) / 2;
    if (target < nums[mid]) return binarySearch(nums, target, lo, mid - 1);
    else if (nums[mid] < target) return binarySearch(nums, target, mid + 1, hi);
    else return mid;
}

第二种:数组中可能含有重复元素,找出目标元素的第一次出现的位置,否则返回该元素的插入位置。

非递归写法:

public int binarySearch(int[] nums, int target) {
    int lo = 0;
    int hi = nums.length - 1;
    while (lo <= hi) {
        int mid = lo + (hi - lo) / 2;
        if (nums[mid] < target) lo = mid + 1;
        else hi = mid - 1;
    }
    return lo;
}

递归写法

public int binarySearch(int[] nums, int target, int lo, int hi) {
    if (lo > hi) return lo;
    int mid = lo + (hi - lo) / 2;
    if (nums[mid] < target) lo = mid + 1;
    else hi = mid - 1;
}

一点经验,二分查找的过程其实很简单,繁琐的点就在于结束的边界处,如果不熟练,一定不要怕麻烦,在纸上多画画检验下,看看最后结果是否正确。一个需要注意的点在于int mid = lo + (hi - lo) / 2;为什么不写成int mid = (lo + hi) / 2呢?因为lo + hi可能会出现整型溢出。

其实上面的求边界还有一种写法:

public int binarySearch(int[] A, int target) {
    int lo = 0
    int hi = A.length;
    while (lo < hi) {
        int mid = lo + (hi - lo) / 2;;
        if (A[mid] < target) {
            lo = mid + 1;
        } else {
            hi = mid;
        }
    }
    return lo;
}

大家可以比较下两种方法的不同点,其实不需要记这么多写法,容易把自己搞混,只需要记住一种正确写法就好。

原文地址:https://www.cnblogs.com/ekoeko/p/9827262.html

时间: 2024-10-10 14:39:45

二分查找(Binary Search)的几种变种形式的相关文章

STL之二分查找 (Binary search in STL)

STL之二分查找 (Binary search in STL) Section I正确区分不同的查找算法count,find,binary_search,lower_bound,upper_bound,equal_range 本文是对Effective STL第45条的一个总结,阐述了各种查找算法的异同以及使用他们的时机. 首先可供查找的算法大致有count,find,binary_search,lower_bound,upper_bound,equal_range.带有判别式的如count_i

【转】STL之二分查找 (Binary search in STL)

Section I正确区分不同的查找算法count,find,binary_search,lower_bound,upper_bound,equal_range 本文是对Effective STL第45条的一个总结,阐述了各种查找算法的异同以及使用他们的时机. 首先可供查找的算法大致有count,find,binary_search,lower_bound,upper_bound,equal_range.带有判别式的如count_if,find_if或者binary_search的派别式版本,其

"二分查找(Binary Search)"与"斐波那契查找(Fibonacci Search)"

首先,我们来看一个笔者的拙作,一段二分查找代码 //返回值是key的下标,如果A中不存在key则返回-1 template <class T> int BinSearch(T* A, const T &key, int lo, int hi) {     int mid;     while(lo<hi)     {         mid = lo + (hi-lo)/2;         if(key < A[mid])             hi = mid-1;

二分查找 Binary Search

简单地用递归的方法实现了二分查找算法,适用于数组. 二分查找算法的前提条件是数组本身是有序的,比如int arr[6] = {2, 3, 5, 7, 11, 13}; 1 int 2 BinarySearch(int arr[], int key, int left, int right) 3 { 4 if (left > right) { 5 return -1; 6 } 7 8 int middle = (left + right) / 2; 9 10 if (arr[middle] ==

折半查找/二分查找 以及二叉树的 三种遍历方式

二分查找   线性查找 1.二分查找 public class BinarySearch { /** * 二分查找 * @param data * @return */ public int binarySearch(long[] data,long n) { //左右 端点 int left =0; int right =data.length-1; //中间元素 int mid=-1; while(left<right){ // 有两种情况 1.left = right 2. left>r

Unique Binary Search Trees 三种解法 python

Given n, how many structurally unique BST's (binary search trees) that store values 1...n? For example,Given n = 3, there are a total of 5 unique BST's. 1 3 3 2 1 \ / / / \ 3 2 1 1 3 2 / / \ 2 1 2 3 递归版,也是AC class Solution: @return an integer # 2014年

算法导论 2.3-5 二分查找

1.二分查找(Binary Search) 二分查找又称折半查找,它是一种效率较高的查找方法.    二分查找要求:线性表是有序表,即表中结点按关键字有序,并且表的存储结构为顺序结构.不妨设有序表是递增有序的. 2.二分查找的基本思想 二分查找算法思想: (1)首先确定该区间的中点位置: mid = ( left + right ) / 2; (2)然后将待查的K值与R[mid].key比较,若相等,则查找成功并返回此位置:否则须确定新的查找区间,继续二分查找,具体方法如下: ①若R[mid].

转:线性表的查找-二分查找

转自:http://student.zjzk.cn/course_ware/data_structure/web/chazhao/chazhao9.2.2.1.htm 二分查找 1.二分查找(Binary Search)     二分查找又称折半查找,它是一种效率较高的查找方法.    二分查找要求:线性表是有序表,即表中结点按关键字有序,并且要用向量作为表的存储结构.不妨设有序表是递增有序的. 2.二分查找的基本思想    二分查找的基本思想是:(设R[low..high]是当前的查找区间) 

Binary Search 二分查找总结

Binary Search基本的复杂度为O(logn).如果提示需要对O(n)的算法进行优化,非常可能就是二分,另外二分一般出现在排序数组或者变形后的排序数组(rotated array)当中.二分主要有两种,binary search on index(index上的二分)和binary search on result(结果上的二分).index上的二分主要有 result上的二分主要有Sqrt(x),Wood cut两种. 另外binary search的版本很多,区别在终结条件,比如是l