【面试高频算法解析】算法练习1 二分查找

2024-01-03 10:38:32

前言

本篇章开放目的是按算法类型学习算法,学习对应算法理论,并通过练习一些经典算法题深入理解这类算法,避免出现刷了很多算法题,还是一知半解的状态


算法解析

二分查找(Binary Search)是一种在有序数组中查找特定元素的高效算法。二分查找的基本思想是通过重复将待搜索的数据范围分成两半,并排除无关的一半,来缩小搜索的范围,直到找到目标值或确定目标值不存在为止。

二分查找的步骤如下:

  1. 确定搜索范围
    初始时,搜索范围是整个数组。

  2. 计算中点
    在当前的搜索范围内,计算中间位置的索引。通常的计算方法是 (low + high) / 2,其中 low 是搜索范围的开始索引,high 是结束索引。为了避免在索引非常大时导致整数溢出,推荐的做法是 low + (high - low) / 2

  3. 比较中点值与目标值
    将中点位置的数组值与目标值进行比较:

    • 如果中点值等于目标值,则查找成功,返回中点索引;
    • 如果中点值小于目标值,则目标值应在中点的右侧,将搜索范围调整为中点右侧的子数组;
    • 如果中点值大于目标值,则目标值应在中点的左侧,将搜索范围调整为中点左侧的子数组。
  4. 重复查找
    根据比较结果调整搜索范围,并在新的范围内重复步骤2和步骤3,直到找到目标值或搜索范围为空(即 low 超过 high),表明目标值不存在。

二分查找的时间复杂度为 O(log n),其中 n 是数组的长度。这使得二分查找比简单的线性查找(O(n))要快得多,尤其是在处理大数据集时。然而,二分查找的前提是数组已经是有序的。如果数组无序,需要先对数组进行排序,排序本身的时间成本可能会影响到整体的效率。

二分查找同时有递归和非递归(迭代)两种实现方式,具体选择哪一种取决于个人偏好和特定场景的需求。


练习题

二分查找

给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。

示例 1:
输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4

示例 2:
输入: nums = [-1,0,3,5,9,12], target = 2
输出: -1
解释: 2 不存在 nums 中因此返回 -1

提示:
你可以假设 nums 中的所有元素是不重复的。
n 将在 [1, 10000]之间。
nums 的每个元素都将在 [-9999, 9999]之间。

复杂度分析
时间复杂度:O(log?n),其中 n 是数组的长度。
空间复杂度:O(1)。

官方题解


在排序数组中查找元素的第一个和最后一个位置

给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值 target,返回 [-1, -1]。
你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。

示例 1:
输入:nums = [5,7,7,8,8,10], target = 8
输出:[3,4]

示例 2:
输入:nums = [5,7,7,8,8,10], target = 6
输出:[-1,-1]

示例 3:
输入:nums = [], target = 0
输出:[-1,-1]

提示:
0 <= nums.length <= 105
-109 <= nums[i] <= 109
nums 是一个非递减数组
-109 <= target <= 109

官方题解


搜索旋转排序数组

整数数组 nums 按升序排列,数组中的值 互不相同 。

在传递给函数之前,nums 在预先未知的某个下标 k(0 <= k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k+1], …, nums[n-1], nums[0], nums[1], …, nums[k-1]](下标 从 0 开始 计数)。例如, [0,1,2,4,5,6,7] 在下标 3 处经旋转后可能变为 [4,5,6,7,0,1,2]。
给你 旋转后 的数组 nums 和一个整数 target ,如果 nums 中存在这个目标值 target ,则返回它的下标,否则返回 -1 。

你必须设计一个时间复杂度为 O(log n) 的算法解决此问题。

示例 1:
输入:nums = [4,5,6,7,0,1,2], target = 0
输出:4

示例 2:
输入:nums = [4,5,6,7,0,1,2], target = 3
输出:-1

示例 3:
输入:nums = [1], target = 0
输出:-1

提示:
1 <= nums.length <= 5000
-104 <= nums[i] <= 104
nums 中的每个值都 独一无二
题目数据保证 nums 在预先未知的某个下标上进行了旋转
-104 <= target <= 104

官方题解

文章来源:https://blog.csdn.net/sinat_41883985/article/details/135339552
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。