二分法细微差异与变种

二分法是一种对于有序数列查找时间复杂度为O(logN)的方法。

常见二分法

最常用的方法是找出该数列中是否含有某一个数字,有则返回其位索引,没有则退出返回-1

while(l<=r){
    mid = (l+r)/2;
    if(arr[mid]==target){
        return mid;
    }
    if (arr[mid]<target){
        l = mid + 1;// 由于除法是向下取整l=mid+1;不然在特定情况下会陷入l=mid的循环
    }
    else{
        r = mid - 1;// r = mid; 是可以的因为只有l=r时才有可能循环
    }
}
return -1;

NOTE 1:  如果行1 (l <= r) 改为 (l<r)则会漏掉当l=r且满足条件的情况

 二分法找数字的第一个索引位或最后一个索引位

不要在找到时停止,直到遍历到第一个索引位或最后一个索引位,同时如果不存在该数字,则返回不大于该数字的最大元素的索引


int realtwosplit(vector<int> arr, int target, int l_flag) {
	int n = arr.size();
	int mid, l = 0, r = n - 1;
	// find the last one which is not bigger than target; l_flag = 1;

	while (l < r) {
		mid = (l + r) / 2;
		if (arr[mid] >target||l_flag && arr[mid]== target) {
			r = mid;//+1;
		}
		else {
			l = mid + 1;
		}
	}
	if (l_flag) {
		if (arr[l] <= target) return l;
		else return l - 1;
	}
	else {
		if (arr[l] < target && arr[l+1]>target) return l;
		else if (arr[l] < target && arr[l + 1] <= target) return l + 1;
		else return l - 1;
	}
	return l;
}

NOTE 2:l_flag作为控制第一索引位的flag

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章