Leetcode 704. 二分查找

本文详细介绍了二分查找算法的三种实现方式:非递归、递归以及优化后的递归实现。代码示例分别用C++和Java语言展示,强调了防止溢出的细节处理。二分查找在有序数组中查找目标元素,具有高效的时间复杂度O(logn)。

题干

代码

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int low=0,high=nums.size()-1;
        while(low<=high){
            // int mid=(low+high)/2;
            int mid=low+(high-low)/2; // 防止溢出 等同于(left + right)/2
            if(nums[mid]>target)
                high=mid-1;
            else if(nums[mid]<target)
                low=mid+1;
            else return mid;
        }
        return -1;
    }
};

--------------------------2022/5/20 复习基本算法---------------------------------

非递归

public static int binarysearch2(int[] arr, int value) {
		int left = 0, right = arr.length-1;

		while (right >= left) {
			int mid = (left + right) / 2;
			if (value == arr[mid]) {
				return mid;
			}
			if (value > arr[mid]) {
				left = mid + 1;
			}
			if (value < arr[mid]) {
				right = mid - 1;
			}
		}
		return -1;
	}

递归

	/**
	 * 递归式二分查找
	 * @param arr
	 * @param left   左
	 * @param right  右
	 * @param digit  要找的数
	 * @return 找到的数的位置
	 */
	
	public static int binarysearch(int[] arr, int left, int right, int digit) {
		int mid = (left + right) / 2;

		// 找不到
		if (right == left) {
			System.out.println("递归式找不到!");
			return -1;
		}
		if (digit > arr[mid]) {
			return binarysearch(arr, mid + 1, right, digit);
		}
		if (digit < arr[mid]) {
			return binarysearch(arr, left, mid - 1, digit);
		}
		if (digit == arr[mid]) {
			return mid;
		}
		return mid;
	}
Leetcode 704题是二分查找的典型题目。二分查找借助数组有序的特点,进行折半查找。 从解题思路来看,由于数组有序,所以可以通过不断缩小查找范围来找到目标值。具体做法是设置 `low = 0`,`heigh = 数组长度 - 1`,`mid = (low + heigh) / 2`。当 `nums[mid] = target` 时,返回 `mid`;当 `nums[mid] < target` 时,所要查找的值在 `mid` 的右边,更新 `low = mid + 1`;当 `nums[mid] > target` 时,所要查找的值在 `mid` 的左边,更新 `heigh = mid - 1`。代码实现如下: ```c int search(int* nums, int numsSize, int target){ int low = 0; int heigh = numsSize - 1; int mid; while(heigh >= low){ mid = (low + heigh) / 2; if(nums[mid] == target){ return mid; } if(nums[mid] < target){ low = mid + 1; } else { heigh = mid - 1; } } return -1; } ``` 从二分查找的整体过程分析,首先要设定左右指针,找出中间位置,并判断该位置值是否等于 `target`。若 `nums[mid] == target` 则返回该位置下标;若 `nums[mid] > target` 则右侧指针移到中间;若 `nums[mid] < target` 则左侧指针移到中间。其时间复杂度为 $O(logN)$ [^2][^3]。 不过二分查找涉及很多边界条件,逻辑虽然简单,但容易出错。例如到底是 `while(left < right)` 还是 `while(left <= right)`,到底是 `right = middle` 还是 `right = middle - 1`,这都需要根据区间的定义来确定 [^5]。 此外,还有不朴素二分查找,即二分查找的循环里左右指针的行为为 `left = mid + 1,right = mid` 或者 `left = mid,right = mid - 1` 这两种情况,需要专门的模板来解决边界处理问题 [^4]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值