二分查找需要注意的地方:整形溢出、死循环

1. 整形溢出

取m和n的中位数,中位数上取整

使用
mid = (m+n+1) / 2
可以避开讨论
m + n + 1
可能导致整形溢出,
可以换成等价写法
m + (n-m+1)/2

死循环

int a[10];

while(l<r){
	m = (l+r)/2; 
	if(){
		l = m;
	}else{
		r = m+1;
	}
}

当数组长度是2时,m和l的值会一直相等,之后死循环

解决方法

m = (l+r+1)/2

二分查找
相同元素时返回第一个和最后一个
查找失败是返回大于目标元素的最小值
或者小于目标元素的最大值


#include <iostream>
#include <functional>
#include <vector>
#include <algorithm>

using namespace std;

#define debug(x) cout<<#x<<": "<<(x)<<endl;

int findLastTarget(vector<int>& arr,int t){

	int l = 0;
	int r = arr.size() - 1;

	int fm = 0;
	int m = 0;
	while (l <= r) {
		m = (l + r) / 2;
		if (arr[m] <= t) {
			fm = m;
			l = m + 1;
		}
		else {
			r = m - 1;
		}
	}
	debug(m)
	return fm;
}

int findFirstTarget(vector<int>& arr, int t){

	int l = 0;
	int r = arr.size() - 1;

	int fm = 0;
	int m = 0;
	while (l <= r) {
		m = (l + r) / 2;
		if (arr[m] >= t) {
			fm = m;
			r = m - 1;
		}
		else {
			l = m + 1;
		}
	}
	debug(m)
	return fm;
}


int main(int argc, char* argv[])
{
	   
	vector<int> arr = {1,2,3,4,4,4,4,4,6,6,7};
	int first = findFirstTarget(arr,4);
	debug(first)
	debug(arr[first])

	int last = findLastTarget(arr,4);
	debug(last)
	debug(arr[last])

	int firstFail = findFirstTarget(arr,5);
	debug(firstFail)
	debug(arr[firstFail])

	int lastFail = findLastTarget(arr,5);
	debug(lastFail)
	debug(arr[lastFail])

	return 0;
}


在这里插入图片描述

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 精致技术 设计师:CSDN官方博客 返回首页