当前位置:   article > 正文

【算法面试】二分查找:如何在有序数组中高效搜索目标值_有序数组查找最优算法

有序数组查找最优算法

目录

题目描述

示例 1:

示例 2:

问题分析

解决方法

方法 1:标准二分查找

方法 2:递归二分查找

方法 3:非递归简化版本

方法 4:带调试信息的版本

详细步骤

总结

博主v:XiaoMing_Java


二分查找是一种常见的算法,广泛应用于计算机科学领域。它的原理是通过不断将目标区间对半划分,从而迅速缩小查找范围。这种方法非常适用于在有序数组中查找特定元素。本篇文章详细解析了如何在有序整型数组中使用二分查找算法来查找目标值,并提供多个代码示例来帮助理解。

题目描述

假设你有一个包含 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

问题分析

二分查找法利用了数组已经排好序(升序)的性质,通过每次将查找范围缩小一半,从而极大地提高了查找效率。算法的核心思想如下:

  1. 选择数组的中间元素作为比较对象。
  2. 如果中间元素正好等于目标值,则直接返回该元素的下标。
  3. 否则,如果目标值小于中间元素,则只需在左半部分继续查找;反之,则在右半部分查找。
  4. 重复上述过程,直到找到目标值或查找范围为空。

解决方法

方法 1:标准二分查找

以下是实现二分查找的一种标准方法:

  1. public int search(int[] nums, int target) {
  2. int left = 0;
  3. int right = nums.length - 1;
  4. while (left <= right) {
  5. int mid = left + (right - left) / 2; // 防止溢出
  6. int x = nums[mid];
  7. if (x == target) {
  8. return mid;
  9. } else if (x > target) {
  10. right = mid - 1;
  11. } else {
  12. left = mid + 1;
  13. }
  14. }
  15. return -1;
  16. }

方法 2:递归二分查找

除了迭代方式,我们还可以采用递归方式实现二分查找:

  1. public int search(int[] nums, int target) {
  2. return binarySearch(nums, target, 0, nums.length - 1);
  3. }
  4. private int binarySearch(int[] nums, int target, int left, int right) {
  5. if (left > right) {
  6. return -1;
  7. }
  8. int mid = left + (right - left) / 2; // 防止溢出
  9. int x = nums[mid];
  10. if (x == target) {
  11. return mid;
  12. } else if (x > target) {
  13. return binarySearch(nums, target, left, mid - 1);
  14. } else {
  15. return binarySearch(nums, target, mid + 1, right);
  16. }
  17. }

方法 3:非递归简化版本

有时我们可以进一步简化代码,使其更简洁:

  1. public int search(int[] nums, int target) {
  2. int left = 0;
  3. int right = nums.length - 1;
  4. while (left <= right) {
  5. int mid = (left + right) / 2;
  6. if (nums[mid] == target) {
  7. return mid;
  8. }
  9. if (nums[mid] < target) {
  10. left = mid + 1;
  11. } else {
  12. right = mid - 1;
  13. }
  14. }
  15. return -1;
  16. }

方法 4:带调试信息的版本

为了更好地理解算法,可以添加调试信息来跟踪程序执行过程:

  1. public int search(int[] nums, int target) {
  2. int left = 0;
  3. int right = nums.length - 1;
  4. while (left <= right) {
  5. int mid = left + (right - left) / 2;
  6. System.out.println("Left: " + left + ", Mid: " + mid + ", Right: " + right);
  7. if (nums[mid] == target) {
  8. System.out.println("Found target at index: " + mid);
  9. return mid;
  10. }
  11. if (nums[mid] < target) {
  12. left = mid + 1;
  13. } else {
  14. right = mid - 1;
  15. }
  16. }
  17. System.out.println("Target not found.");
  18. return -1;
  19. }

详细步骤

  1. 初始化:设置 left 为数组的起始索引 0right 为数组的末尾索引 n-1
  2. 计算中点:在每个迭代中,计算中点 mid 的索引,避免直接加和可能导致的溢出。
  3. 比较中点值:将中点值与目标值 target 比较:
    • 若相等,返回中点索引。
    • 若中点值大于目标值,将 right 更新为 mid - 1
    • 若中点值小于目标值,将 left 更新为 mid + 1
  4. 重复操作:继续上述步骤直到 left 超过 right,表示目标值不在数组中,返回 -1

总结

二分查找是一种高效的查找算法,其时间复杂度为 O(log n),非常适用于大规模有序数组的查找任务。通过本文展示的多种实现方法,你可以灵活选择适合自己场景的实现方式。此外,理解并掌握二分查找的基本原理和细节,将会对提升你的编码能力和解决问题的效率大有裨益。希望这些方法能够帮助你顺利解决 java.util.concurrent.BrokenBarrierException 问题,确保程序顺利运行。

如果本文对你有帮助 欢迎 关注、点赞、收藏、评论!!!

博主v:XiaoMing_Java

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/796069
推荐阅读
相关标签