二分查找

二分

二分可以看做优化版的枚举

二分简介

  • 二分法是一种在有序数组中查找特定元素的高效算法。它通过将查找范围一分为二,然后根据中间元素与目标元素的比较结果,决定继续在左半部分还是右半部分查找,从而逐步缩小查找范围,直到找到目标元素或确定目标元素不存在。

二分的特点

  • 可以进行查找
  • 速度快,效率高
  • 可以用于任何数组
  • 实现简单

二分的原理

  • 二分法是利用了二段性,将区间一分为二,然后判断答案在左区间还是右区间,然后递归处理。
  • 二分法一般用于求解单调函数最值问题,即求函数的最大值最小值
  • 二分法的时间复杂度是O(logn),其中n是区间的长度。
    二分法的关键在于确定每次二分后,答案在左区间还是右区间,然后递归处理。

二分的流程

  • 确定二分区间,一般是一个有序的区间。
  • 确定二分条件,即如何判断答案在左区间还是右区间。
  • 确定二分终止条件,即如何判断二分已经找到答案。
  • 确定二分更新方式,即如何更新二分区间。

二分与枚举的区别

枚举二分
时间复杂度O(n)O(logn)
空间复杂度O(1)O(1)
适用范围任何数组单调函数
实现难度简单相对枚举稍难

二分模板

  • 二分模板

C++

int l = 0, r = n - 1;
while (l < r) {
    int mid = (l + r) >> 1;
    if (check(mid)) {
    
}

Python

l = 0
r = n - 1
while l < r:
    mid = (l + r) >> 1
    if check(mid):

二分查找

  • 二分查找是一种在有序数组中查找特定元素的算法。它通过将查找区间一分为二,然后根据比较结果决定在左半部分还是右半部分继续查找,从而逐步缩小查找范围,直到找到目标元素或确定目标元素不存在。
  • 二分查找的时间复杂度为O(logn),其中n是数组的长度。这是因为它每次都将查找区间缩小一半,因此查找次数最多为logn次。
  • 二分查找的算法流程如下:
  • 初始化左边界l为0,右边界r为数组长度减1。
  • 当l小于r时,执行以下步骤:
  • 计算中间位置mid,即mid = (l + r) // 2。
  • 比较目标元素target与数组中mid位置的元素:
  • 如果target等于数组中mid位置的元素,则返回mid。
  • 如果target小于数组中mid位置的元素,则将右边界r更新为mid - 1。
  • 如果target大于数组中mid位置的元素,则将左边界l更新为mid + 1。
  • 如果循环结束后仍未找到目标元素,则返回-1,表示目标元素不存在于数组中。
  • 二分查找的算法实现如下:

C/C++

int binarySearch(vector<int>& nums, int target) {
    int l = 0, r = nums.size() - 1;
    while (l < r) {
        int mid = (l + r) / 2;
        if (nums[mid] == target) {
            return mid;
        } else if (nums[mid] < target) {
            l = mid + 1;
        } else {
            r = mid - 1;
        }
    }
    return -1;
}

Python3

def binary_search(nums, target):
    l, r = 0, len(nums) - 1
    while l < r:
        mid = (l + r) // 2
        if nums[mid] == target:
            return mid
        elif nums[mid] < target:
            l = mid + 1
        else:
            r = mid - 1
    return -1

Java

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

JavaScript

function binarySearch(nums, target) {
    let l = 0, r = nums.length - 1;
    while (l < r) {
        const mid = Math.floor((l + r) / 2);
        if (nums[mid] === target) {
            return mid;
        } else if (nums[mid] < target) {
            l = mid + 1;
        } else {
            r = mid - 1;
        }
    }
    return -1;
}

Go

func binarySearch(nums []int, target int) int {
    l, r := 0, len(nums)-1
    for l < r {
        mid := (l + r) / 2

        if nums[mid] == target {
            return mid
        } else if nums[mid] < target {
            l = mid + 1
        } else {
            r = mid - 1
        }
    }
    return -1
}

TypeScript

function binarySearch(nums: number[], target: number): number {
    let l = 0, r = nums.length - 1;
    while (l < r) {
        const mid = Math.floor((l + r) / 2);
        if (nums[mid] === target) {
            return mid;
        } else if (nums[mid] < target) {
            l = mid + 1;
        } else {
            r = mid - 1;
        }
    }
    return -1;
}

PHP

function binarySearch($nums, $target) {
    $l = 0;
    $r = count($nums) - 1;
    while ($l < $r) {
        $mid = floor(($l + $r) / 2);
        if ($nums[$mid] === $target) {
            return $mid;
        } elseif ($nums[$mid] < $target) {
            $l = $mid + 1;
        } else {
            $r = $mid - 1;
        }
    }
    return -1;
}

Ruby

def binary_search(nums, target)
    l, r = 0, nums.length - 1
    while l < r
        mid = (l + r) / 2
        if nums[mid] == target
            return mid
        elsif nums[mid] < target
            l = mid + 1
        else
            r = mid - 1

        end
    end
    -1
end

Rust

fn binary_search(nums: Vec<i32>, target: i32) -> i32 {
    let mut l = 0;
    let mut r = nums.len() - 1;
    while l < r {
        let mid = (l + r) / 2;
        if nums[mid] == target {
            return mid as i32;
        } else if nums[mid] < target {
            l = mid + 1;
        } else {
            r = mid - 1;
        }
    }
    -1
}

C#

public int BinarySearch(int[] nums, int target)
{
    int l = 0;
    int r = nums.Length - 1;
    while (l < r)
    {
        int mid = (l + r) / 2;
        if (nums[mid] == target)
        {
            return mid;
        }
        else if (nums[mid] < target)
        {
            l = mid + 1;
        }
        else
        {
            r = mid - 1;
        }
    }
    return -1;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值