前端算法·专项攻破二:二分查找&排序

543 阅读3分钟

概念理解

什么是二分?

在计算机科学中,二分查找算法(英语:binary search algorithm),也称折半搜索算法(英语:half-interval search algorithm)、对数搜索算法(英语:logarithmic search algorithm),是一种在有序数组中查找某一特定元素的搜索算法。

使用场景

采用二分法查找时,数据需是排好序的。

例题讲解

题目:二分查找-I

描述

请实现无重复数字的升序数组的二分查找

给定一个 元素升序的、无重复数字的整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标(下标从 0 开始),否则返回 -1

示例1

输入:

[-1,0,3,4,6,10,13,14],13

返回值:

6

说明:

13 出现在nums中并且下标为 6     

示例2

输入:

[],3

返回值:

-1

说明:

nums为空,返回-1     

示例3

输入:

[-1,0,3,4,6,10,13,14],2

返回值:

-1

说明:

2 不存在nums中因此返回 -1     

题解

/**
 * 解法一:循环
 * 思路:
 * (1)从数组首尾开始,每次取中点值。
 * (2)如果中间值等于目标即找到了,可返回下标,如果中点值大于目标,
 *  说明中点以后的都大于目标,因此目标在中点左半区间,如果中点值小于目标,则相反。
 * (3)根据比较进入对应的区间,直到区间左右端相遇,意味着没有找到。
 * 时间复杂度:O(log2n),对长度为n的数组进行二分,最坏情况就是取2的对数
 * 空间复杂度:0(1),无额外空间
 */
export function search(nums: number[], target: number): number {
    const len = nums.length
    if (len === 0) return -1

    let startIndex = 0
    let endIndex = len - 1

    while (startIndex <= endIndex) {
        const midIndex = Math.floor((startIndex + endIndex) / 2) // 将数字向下舍入到最接近的整数
        const midValue = nums[midIndex]

        if (target < midValue) {
            // 目标值较少,则继续在左侧查找 
            endIndex = midIndex - 1
        } else if (target > midValue) {
            // 目标值较大,则继续在右侧查找 
            startIndex = midIndex + 1
        } else {
            return midIndex
        }
    }

    return -1
};

/**
 * 解法二:递归
 * 思路:
 * (1)从数组首尾开始,每次取中点值。
 * (2)如果中间值等于目标即找到了,可返回下标,如果中点值大于目标,说明中点以后的都大于目标,
 *  因此目标在中点左半区间,如果中点值小于目标,则相反。
 * (3)根据比较进入对应的区间,直到区间左右端相遇,意味着没有找到。
 * 时间复杂度:O(logn),对长度为n的数组进行二分,最坏情况就是取2的对数
 * 空间复杂度:0(1)
 */
 function search(nums: number[], target: number, startIndex?: number, endIndex?: number): number {
    const len = nums.length;
    if (len === 0) return -1;

    // 开始和结束的范围
    if (startIndex == null) startIndex = 0
    if (endIndex == null) endIndex = len - 1

    // 如果 start 和 end 相遇则结束
    if (startIndex > endIndex) return -1

    // 中间位置
    const midIndex = Math.floor((startIndex + endIndex) / 2)
    const midValue = nums[midIndex]

    if (target < midValue) {
        // 目标值较小,则继续在左侧查找
        return search(nums, target, startIndex, midIndex - 1)
    } else if (target > midValue) {
        // 目标值较大,则继续在右侧查找
        return search(nums, target, midIndex + 1, endIndex)
    } else {
        // 相等,返回
        return midIndex
    }
};

题集&题解

序号题目题解难度
1二分查找-I题解easy
2二维数组中的查找题解medium
3寻找峰值题解medium
4数组中的逆序对题解medium
5旋转数组的最小数字题解easy
6比较版本号题解medium

相关文章

您的点赞和评论是我持续更新的动力,感谢关注。