自学内容网 自学内容网

每日一题-二分查找

二分查找实现:寻找目标值在升序数组中的位置

题目描述

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

函数签名
int search(int* nums, int numsLen, int target);
输入
  • nums:一个整数数组,数组中的元素为升序排列且没有重复元素。
  • numsLen:整数,数组 nums 的长度。
  • target:目标整数,表示需要在数组中查找的数值。
输出
  • 返回目标值 target 在数组 nums 中的下标。如果目标值不存在,返回 -1
数据范围
  • 数组长度:$ 0 \leq len(nums) \leq 2 \times 10^5 $
  • 数组元素范围:$ |val| \leq 10^9 $
进阶要求
  • 时间复杂度:$ O(\log n) $
  • 空间复杂度:$ O(1) $
示例

示例1

输入:

int nums[] = {-1, 0, 3, 4, 6, 10, 13, 14};
int target = 13;

输出:

6

说明:13 出现在数组 nums 中且下标为6。

示例2

输入:

int nums[] = {};
int target = 3;

输出:

-1

说明:数组为空,返回 -1。

示例3

输入:

int nums[] = {-1, 0, 3, 4, 6, 10, 13, 14};
int target = 2;

输出:

-1

说明:2 不存在数组 nums 中,因此返回 -1。

解题思路

由于数组是升序且无重复的,我们可以使用二分查找来提高搜索效率。二分查找的时间复杂度为 $ O(\log n) $,符合题目要求。

代码实现

/**
 * 实现二分查找,寻找目标值在数组中的位置
 * 
 * @param nums int整型一维数组,升序且无重复
 * @param numsLen int nums数组长度
 * @param target int 目标值
 * @return int 目标值在数组中的下标,如果不存在返回 -1
 */
int search(int* nums, int numsLen, int target) {
    // 初始化左右指针,分别指向数组的开头和结尾
    int left = 0;
    int right = numsLen - 1;

    // 开始二分查找循环
    while (left <= right) {
        // 计算中间位置,避免 (left + right) 可能出现的溢出
        int mid = left + (right - left) / 2;

        // 判断中间值是否等于目标值
        if (nums[mid] == target) {
            return mid;  // 找到目标值,返回下标
        } else if (nums[mid] < target) {
            // 如果中间值小于目标值,说明目标值在右半部分
            left = mid + 1;
        } else {
            // 如果中间值大于目标值,说明目标值在左半部分
            right = mid - 1;
        }
    }

    // 如果退出循环,说明没有找到目标值
    return -1;
}
代码解析
  1. 初始化左右指针:
    left 初始化为 0,right 初始化为 numsLen - 1,分别指向数组的开头和结尾。

  2. 二分查找过程:
    通过计算 mid = left + (right - left) / 2 来避免可能的溢出,查找数组中间的元素。如果 nums[mid] == target,则返回 mid。如果 nums[mid] < target,目标值在右侧,更新 left = mid + 1;如果 nums[mid] > target,目标值在左侧,更新 right = mid - 1

  3. 查找结束:
    如果循环结束仍未找到目标值,返回 -1

时间复杂度
  • 每次查找都将查找范围缩小一半,因此时间复杂度为 $ O(\log n) $。
空间复杂度
  • 只使用了常数空间来存储指针和中间值,因此空间复杂度为 $ O(1) $。

总结

最开始我还想着,除以二余数的问题,但是后来才想到,其实本质上就是层层靠近的问题,每一次更新后,leaf或者right铁定更加靠近目标值,所以根本不用担心靠近的问题。


原文地址:https://blog.csdn.net/zxjiaya/article/details/145247263

免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!