lower_bound算法返回第一个大于等于给定值所在的位置。设置两个指针start和last,其中start指向数组的起始位置,last指向数组末尾位置之后的位置。当start和last指向相同位置时循环结束。mid指向[start,last)区间的中间位置,当中间位置元素值大于等于给定val时,说明第一个大于等于val值在mid位置的左边,更新last为mid。当中间位置元素值小于给定的val时,说明第一个大于等于val值在mid右边,不包括mid所在的位置。更新start为mid+1。
int myLowerBound(vector<int> &data, int k)
{int start = 0;int last = data.size();while (start < last){int mid = (start + last) / 2;if (k > data[mid]) start = mid + 1;else last = mid;}return start;
}
upper_bound算法返回第一个大于给定元素值所在的位置,设置两个指针start和last,其中start指向数组的起始位置,last指向数组末尾位置之后的位置,当start和last指向相同位置时循环结束,mid指向[start,last)区间的中间位置,当中间位置元素值小于等于给定val时,说明第一个大于val值在mid位置的右边更新start为mid+1。当中间位置元素值大于给定元素时,说明第一大于在mid左边,包括mid所在位置,所以更新last为mid。
int myUpperBound(vector<int> &data, int k)
{int start = 0;int last = data.size();while (start < last){int mid = (start + last) / 2;if (k >= data[mid]) start = mid + 1;else last = mid;}return start;
}
以上都是,左端是满足值。特点就是都是l永远都是=mid+1,r永远都是=mid
下面再来一发,右端是满足值的(至于是lower还是upper,就看ok函数中加不加等号就可以了):(找一个特例,比如只有两个值的模拟一下)
while(l<r) {m=(l+r+1)/2;if(ok()) l=m;else r=m-1;}printf("l = %d\n",l);
等价于:(左端满足值的就是在else中ans=m就可以了,比较好实现)
while(l<=r) {m=(l+r)/2;if(ok()) l=m+1,ans=m;else r=m-1;}printf("ans = %d\n",ans);
关于binarysearch https://blog.csdn.net/daniel_ustc/article/details/17307937
upper_bound再来一种实现:
int Search(int num,int low,int high)
{int mid;while(low<=high){mid=(low+high)/2;if(num>=b[mid]) low=mid+1;else high=mid-1;} return low;
}
纪念编辑时间:2018.10.08 10:12:42