思路很简单,细节最致命,不要看不起看似很简单的二分法,不同的细节决定了它不同的用途!!!

普通二分查找

找到则返回下标,找不到返回-1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int search(vector<int>& nums,int target)
{
int low = 0;
int high = nums.size()-1;
int mid = 0;
while(low<=high)
{
mid = (low+high)/2;
if(target<nums[mid])
{
high=mid-1;
}
else if (target>nums[mid])
{
low=mid+1;
}
else
{
return mid;
}
}
return -1;
}

查找插入位置

给出一个升序数组,一个数字,从数组中找出该数字的插入位置,可以这样想:循环结束的条件(假设插入的数字数组中没有)是low=high+1,此时target必然array[high] < target < array[low],因此插入位置一定是low处

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 int searchInsert(vector<int>& nums, int target) {
int low = 0;
int high = nums.size()-1;
int middle = 0;
while (low <= high)
{
middle = (low + high) / 2;
if (nums[middle] == target)
{
return middle;
}
else if (target > nums[middle])
{
low = middle + 1;
}
else
{
high = middle - 1;
}
}
return low;
}

查找上下界

给出一个升序数组(可能有重复),一个数字,从数组中找出该数字的下界

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int searchRange(vector<int>& nums, int target)
{
int low = 0;
int high = nums.size() - 1;
int mid = 0;
while (low <= high)
{
mid = (low + high) / 2;
if (target <= nums[mid])
{
high = mid - 1;
}
else
{
low = mid + 1;
}
}
if(low>=nums.size() || nums[low]!=target)
return -1;
return low;
}

给出一个升序数组(可能有重复),一个数字,从数组中找出该数字的上界

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int searchRange(vector<int>& nums, int target)
{
int low = 0;
int high = nums.size() - 1;
int mid = 0;
while (low <= high)
{
mid = (low + high) / 2;
if (target >= nums[mid])
{
low = mid + 1;
}
else
{
high = mid - 1;
}
}
if(high<0 || nums[high]!=target)
return -1;
return high;
}