面试现场:手撕二分查找算法

算法概述

二分搜索,也称折半搜索、对数搜索,是一种在有序数组中查找某一特定元素的搜索算法。

搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组为空,则代表找不到。这种搜索算法每一次比较都使搜索范围缩小一半。

二分搜索在情况下的复杂度是对数时间,进行 O(log n)次比较操作(n在此处是数组的元素数量, O是大O记号, log 是对数)。

二分搜索使用常数空间,无论对任何大小的输入数据,算法使用的空间都是一样的。除非输入数据数量很少,否则二分搜索比线性搜索更快,但数组必须事先被排序。

示例代码

Java代码(循环)

    /**
     * 二分查找(循环)
     * @param arr 数组
     * @param start 头索引
     * @param end 尾索引
     * @param target 目标
     * @return 目标索引
     */
    public static int binarySearchByRecursion(int[] arr, int start, int end, int target){
        int result = -1;

        while (start <= end){
            int mid = start + (end - start)/2;    //防止溢位
            if (arr[mid] > target)
                end = mid - 1;
            else if (arr[mid] < target)
                start = mid + 1;
            else {
                result = mid ;
                break;
            }
        }
        return result;
    }

Java代码(递归)

    /**
     * 二分查找(递归)
     * @param arr 数组
     * @param start 头索引
     * @param end 尾索引
     * @param target 目标
     * @return 目标索引
     */
    public static int binarySearch(int[] arr, int start, int end, int target){
        if (start > end) {
            return -1;
        }
        int mid = start + (end - start)/2;    //防止溢位
        if (arr[mid] > target) {
            return binarySearch(arr, start, mid - 1, target);
        }
        if (arr[mid] < target)
            return binarySearch(arr, mid + 1, end, target);
        return mid;
    }

复杂度分析

时间复杂度

折半搜索每次把搜索区域减少一半,每次查找的区间大小就是n,n/2,n/2/2,n/2/2/2,简化为n/2^k,时间复杂度也就是查找的次数k,最终的区间大小必定为1,即 n/2^k=1,所以 k=log2 n。(读作:log以2为底n的对数)

空间复杂度

O(1),常数空间,无论对任何大小的输入数据,算法使用的空间都是一样的。

原文地址:https://www.cnblogs.com/yueshutong/p/11367901.html

时间: 2024-10-05 23:25:40

面试现场:手撕二分查找算法的相关文章

手撕二分查找及其变种,就是干!

一.初探二分查找 在面试的时候,尤其的一面,感觉让你手写二分,还真的不一定就能很快写出来,所以在此总结分享给大家 1 二分查找是什么? "查找"顾名思义是在一堆数去找出我们需要的数,但是我们又想更快的找出我们需要找的数,所以我们就尽量的减少查找比较的次数."二分"就是分成两份来减少我们查找次数. 不急不急,假设我们这里有十个数,我们来画图看看这是个什么神操作. 从上图我们知道,我们每次都和区间的中间项值进行比较,从而缩小查找区间的值. 2 时间复杂度? 这里我们假设

基础算法介绍 —— 二分查找算法

不知不觉在目前的公司待满3年了,打算回家找份工作.面试中被问到关于算法的题目:有哪些常见的查找算法?下来就把我所掌握的查找算法分享给大家,本文主要介绍二分查找算法. 算法定义(摘自百度):二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好:其缺点是要求待查表为有序表,且插入删除困难.因此,折半查找方法适用于不经常变动而查找频繁的有序列表.首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功:否则利用中间位置记录将表分成前.后两个子表,如果

Python 实现二分查找算法

最近在学习python,由于在面试中,二分查找算法面试率极高,所以使用python做了一个实现. def search1(sequence, number): lower = 0 upper = len(sequence) - 1 while lower <= upper: mid = (lower + upper) // 2 if number > sequence[mid]: lower = mid + 1 elif number < sequence[mid]: upper = m

二分查找算法的 JavaScript 实现

二分查找在查找[指定值]在[有序]数据中的[位置]时是一种高效的算法. 以下仅提供 ES5 版本. var arr = [0, 2, 4, 27, 28, 54, 67, 74, 75, 79, 86, 97, 289, 290, 678] function binarySearch(arr, val) { var start = 0, end = arr.length - 1; while (start <= end) { var mid = Math.floor((start + end)

算法_001_二分查找算法

 二分查找算法是在有序数组中用到的较为频繁的一种算法,在未接触二分查找算法时,最通用的一种做法是,对数组进行遍历,跟每个元素进行比较,其时间为O(n).但二分查找算法则更优,因为其查找时间为O(lgn),譬如数组{1, 2, 3, 4, 5, 6, 7, 8, 9},查找元素6,用二分查找的算法执行的话,其顺序为:     1.第一步查找中间元素,即5,由于5<6,则6必然在5之后的数组元素中,那么就在{6, 7, 8, 9}中查找,    2.寻找{6, 7, 8, 9}的中位数,为7,7>

Java学习之二分查找算法

好久没写算法了.只记得递归方法..结果测试下爆栈了. 思路就是取范围的中间点,判断是不是要找的值,是就输出,不是就与范围的两个临界值比较大小,不断更新临界值直到找到为止,给定的集合一定是有序的. 自己写的代码: 1 package com.gh; 2 3 import java.util.Arrays; 4 /** 5 * 二分查找算法实现 6 * @author ganhang 7 * 8 */ 9 public class Search { 10 public static void mai

二分查找算法java实现

今天看了一下JDK里面的二分法是实现,觉得有点小问题.二分法的实现有多种今天就给大家分享两种.一种是递归方式的,一种是非递归方式的.先来看看一些基础的东西. 1.算法概念. 二分查找算法也称为折半搜索.二分搜索,是一种在有序数组中查找某一特定元素的搜索算法.请注意这种算法是建立在有序数组基础上的. 2.算法思想. ①搜素过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜素过程结束: ②如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间

二分查找算法

提到查找算法,最经典的就是二分查找算法了.在二分查找时要在有序的数据里查找目标target,先取中间元素与target比较, 当target小于中间元素的时候,则搜索数组的前半部分,target大于中间元素时,则取数组的后半部分.重复整个搜索的过程 将左半部分与有半部分当作子数组继续查找,直到找到元素或到子数组的大小为0停止. 原理上很简单却有较多细节,尤其是数据边界的取值是否会越界,while循环的条件. java code: public class BinarySearchDemo { p

python函数:递归函数及二分查找算法

本文和大家分享的主要是python的递归函数及二分查找算法相关内容,一起来看看吧,希望对大家学习python有所帮助. 一.递归的定义 def story(): s = """ 从前有个山,山里有座庙,庙里老和尚讲故事, 讲的什么呢? """ print(s) story() story() 老和尚讲故事 递归的定义 -- 在一个函数里再调用这个函数本身.这种魔性的使用函数的方式就叫做 递归 . 递归的最大深度:997 1.python递归最大层