二分总结

来源:互联网 发布:期货软件app 编辑:程序博客网 时间:2024/05/22 16:46

http://blog.csdn.net/int64ago/article/details/7425727

今天求最长非递减子序列的时候,用lower—bound一直wa,百思不得其解,最后想明白不是找第一个大于等于的数,而是找到第一个大于的数。所以只能自己手写二分了,原来一直以为二分很简单,但是今天写了之后发现总是有各种小错误。比如while (left < right)和while (left <= right) 的选择,比如a[mid] > key 和a[mid] >= key 的选择。直到看到上面那篇博客,受益匪浅,不过就我今天写的题还有一些要添加的内容。

先贴出上面博客的几种情况的二分

Hint: begin是第一个元素的下标,end是最后一个元素的下标加1

YES_LEFT (如果有多个元素,返回最左边一个元素的下标)或 NO_RIGHT(如果没有,返回key可以插入位置的下一个元素下标)

int Binary_search(int begin, int end, int key)  {      int left = begin, right = end, mid;      while(left <= right)      {          mid = (left + right) >> 1;          if(num[mid] >= key)             right = mid - 1;          else left = mid + 1;      }      return left;  } 
YES_RIGHT(如果有多个元素,返回最右边一个元素的下标) 或 NO_LEFT(如果没有,返回key可以插入位置的前一个元素)

    int Binary_search(int begin, int end, int key)      {          int left = begin, right = end, mid;          while(left <= right)          {              mid = (left + right) >> 1;              if(num[mid] > key)                 right = mid - 1;              else left = mid + 1;          }          return right;      }  
但是我今天需要的并不是上面任何一种的二分,我要求的二分是,返回一个数组中第一个大于key的值的下标

int Binary_search(int begin, int end,int key){    int left = begin, right = end, mid;    while(left <= right)    {        mid = (left + right) >> 1;        if(num[mid] > key)            right = mid - 1;        else left = mid + 1;    }    return left;}
那么还有最后一种二分,它的功能是找出最后一个比key值小的元素的下标,如果所有元素都大于等于key,返回0。
int Binary_search(int begin, int end, int key){    int left = begin, right = end, mid;    while(left <= right)    {        mid = (left + right) >> 1;        if(num[mid] >= key)            right = mid - 1;        else left = mid + 1;    }    return right;}
上面四种代码可以实现我们想要的功能,假如我们现在想要的功能是,查找元素,如果有多个,返回最左边的下标,如果没有,返回-1。我们可以从YES_LEFT修改得出,

只要最后判断返回下标所代表的元素是不是key,就可以知道key到底存在不存在。

int Binary_search(int begin, int end, int key){    int left = begin, right = end, mid;    while(left <= right)    {        mid = (left + right) >> 1;        if(num[mid] >= key)            right = mid - 1;        else left = mid + 1;    }    if (num[left] == key)        return left;    else return -1;}



0 0
原创粉丝点击