二分法

二分查找是常用的查找方式之一,
它针对于有序数组,
是一种在每次比较之后将查找空间一分为二的算法。

二分查找的三个步骤:

预处理 —— 如果集合未排序,则进行排序。
二分查找 —— 使用循环或递归在每次比较后将查找空间划分为两半。
后处理 —— 在剩余空间中确定可行的候选者。

二分法常见的模版三种类型:
1.(left <= right)

int l = 0, r = nums.length - 1;
while(l <= r){
	int mid = l + (r - l) / 2;
	//查找条件因条件而定
	if(nums[mid] > terget)	r = end - 1;
	else if(nums[mid] < terget)	l = mid + 1;
	else	return mid;
}

此模版每一步中,都在检查是否找到了元素。如果到达末尾,则知道未找到该元素。

2.(left < right)

int l = 0, r = nums.length - 1;
while(l < r){
	int mid = l + (r - l) / 2;
	//查找条件因条件而定
	if(nums[mid] < target)	l = mid + 1;
	else r = mid;
}

在夹逼过程中,对于 l 与 r 的取值具体等于多少可由具体情况而定,尤其在同一数组从一个数分割,两边排序时,当寻找右边取值时,则向右夹逼,即 l = mid; 向左是反之即可。当你剩下 1 个元素时,循环 / 递归结束。 需要评估剩余元素是否符合条件,符合条件则输出 l 或nums[l]。

3.(left + 1 < right)

int l = 0, r = nums.length - 1;
while(l + 1 < r){
	int mid = l + (r - l) / 2;
	//查找条件因条件而定
	if(nums[mid] > target)	l = mid;
    else    r = mid;
}

保证查找空间在每个步骤中至少有 3 个元素,当剩下 2 个元素时,循环 / 递归结束。 需要评估其余元素是否符合条件。

二分法入门相关可参考leetcode给出的相关分类,也可以刷PAT上的习题,PAT甲级习题分类我已经整理好了,可以在我的其他博客上查看。
(其实我觉得有些二分查找的练习题,从双指针的角度来讲更容易理解Orz。)

你可能感兴趣的:(二分法)