二分法細微差異與變種

二分法是一種對於有序數列查找時間複雜度爲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

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