题目
给定一个 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]
之间
一、二分查找是什么?
查找过程
首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。
算法要求
1.必须采用顺序存储结构。
2.必须按关键字大小有序排列。
二、代码实现
1.非递归实现
代码如下(示例):
class Solution {
public int search(int[] nums, int target) {
int left=0;
int right=nums.length;
while(left<right){
int middle=(right+left)/2;
if(target<nums[middle])right=middle;
else if(target==nums[middle])return middle;
else left=middle+1;
}
return -1;
}
}
2.递归实现
代码如下(示例):
class Solution {
public int search(int[] nums, int target) {
return dfs(0, nums.length - 1, nums, target);
}
public int dfs(int left, int right, int[] nums, int target) {
int mid = (left + right) / 2;
// 终止条件
if (left > right) return -1;
if (target == nums[mid]) return mid;
// 向左查找
if (target < nums[mid]) return dfs(left, mid - 1, nums, target);
// 向右查找
if (target > nums[mid]) return dfs(mid + 1, right, nums, target);
return 0;
}
}