二分法查找,也称折半法,是一种在有序数组中查找特定元素的搜索算法。
二分法查找步骤
-
首先,从数组的中间开始搜索,如果该元素正好是目标元素,则搜索过程结束,否则执行下一步。
-
如果中间元素>目标元素,则在数组小于中间元素的那一半区域在进行二分查找;如果中间元素<目标元素,则在数组大于中间元素的那一半区域再进行二分查找。
-
如果某一步数组为空,则表示找不到目标元素。
二分查找时间复杂度
- 时间复杂度:O(logn)
二分查找代码
public int binarySearch(int[] arr, int key) {
int low = 0, high = arr.length-1;
while(low <= high) {
int mid = (low + high)/2;
if(arr[mid] == key) {
return mid;
}else if(arr[mid] > key) {
high = mid - 1;
}else if(arr[mid] < key) {
low = mid + 1;
}
}
return -(low+1);
}
二分查找实例
给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
示例 1:
输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
示例 2:
输入:target = 4, nums = [1,4,4]
输出:1
示例 3:
输入:target = 11, nums = [1,1,1,1,1,1,1,1]
输出:0
提示:
- 1 <= target <= 109
- 1 <= nums.length <= 105
- 1 <= nums[i] <= 105
题目来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-size-subarray-sum
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int n = nums.length;
int[] sums = new int[n+1];
int min = Integer.MAX_VALUE;
for(int i = 1; i<n+1; i++){
sums[i] = sums[i-1] + nums[i-1];
}
for(int i=1; i<n+1; i++){
int newTarget = target + sums[i-1];
int rtn = Arrays.binarySearch(sums, newTarget);
if(rtn < 0){
rtn = -rtn-1;
}
if(rtn <= n){
min = Math.min(min, rtn-i+1);
}
}
return min==Integer.MAX_VALUE ? 0 : min;
}
}
int minSubArrayLen(int target, int* nums, int numsSize){
int i, newTarget, rtn, sums[numsSize+1];
int min = 0x7fff;
for(i=1; i<numsSize + 1; i++){
sums[i] = sums[i-1] + nums[i-1];
};
for(i=1; i<numsSize+1; i++){
newTarget = target + sums[i-1];
rtn = binarySearch(sums, numsSize+1, newTarget);
printf("%d\n", rtn);
if(rtn < 0){
rtn = -rtn;
};
if(rtn <= numsSize){
rtn = rtn-i+1;
min = fmin(min, rtn);
}
};
return min == 0x7fff ? 0 : min;
}
int binarySearch(int *nums, int numsSize, int target){
int low = 0, high = numsSize-1;
int mid;
while(low <= high){
printf("low=%d\n", low);
mid = (low + high)/2;
printf("mid=%d\n", mid);
if(nums[mid] == target){
return mid;
}else if(nums[mid] < target){
low = mid + 1;
}else{
high = mid - 1;
}
};
return - low;
}