LeetCode-704. 二分查找(C语言)

目录捏

  • 一、题目描述
  • 二、示例与提示
  • 三、思路
  • 四、代码


一、题目描述

给定一个 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. 你可以假设 nums 中的所有元素是不重复的。
  2. n 将在 [1, 10000] 之间。
  3. nums 的每个元素都将在 [-9999, 9999] 之间。

三、思路

本题的前提是数组为有序数组,同时题目还强调数组中无重复元素,因为一旦有重复元素,使用二分查找法返回的元素下标可能不是唯一的,这些都是使用二分法的前提条件

二分查找就涉及到边界条件问题,区间的定义就是不变量,要在二分查找的过程中,保持不变量,就是在while寻找中每一次边界的处理都要坚持根据区间的定义来操作,这就是循环不变量规则

本题定义 target 是在一个在左闭右闭的区间里,也就是 [left, right],所以需要注意如下两点:

  • while (left <= right) 要使用 <= ,因为left == right是有意义的,所以使用 <=
  • if (nums[middle] > target) right 要赋值为 middle - 1,因为当前这个nums[middle]一定不是target,那么接下来要查找的左区间结束下标位置就是 middle - 1

例如在数组:1,2,3,4,7,9,10中查找元素2,如图所示:

LeetCode-704. 二分查找(C语言)_第1张图片

四、代码

// 左闭右闭区间 [left, right]
int search(int* nums, int numsSize, int target){
    int left = 0;
	int right = numsSize - 1;
	int middle;
	// 若left小于等于right,说明区间中元素不为0
	while (left <= right)
	{
		// 更新下标middle值
		middle = (left + right) / 2;
		// 此时target缩减范围至[left,middle-1]区间中
		if (nums[middle] > target)
			right = middle - 1;
		// 当前下标元素等于target值时,返回middle
		else if (nums[middle] == target)
			return middle;
		// 此时target缩减范围至[middle+1,right]区间中
		else
			left = middle + 1;
	}
	// 若未找到target元素,返回-1
	return -1;
}

复杂度分析

时间复杂度: O(log n)

你可能感兴趣的:(力扣,1024程序员节,c语言,leetcode)