zoukankan      html  css  js  c++  java
  • 二分

    二分是个很实用的算法,每次运算区间均缩小一半,因此时间复杂度是logN

    下面给出简约版二分算法:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=1e6+7;
     4 int n,m,l,arr[maxn];
     5 int find(int x)
     6 {
     7     int mid;
     8     int left=-1;///开始坐标-1;
     9     int right=n;///结束坐标+1;
    10     while(left+1<right)
    11     {
    12         mid=(left+right)/2;
    13         if(arr[mid]<=x)
    14             left=mid;
    15         else
    16             right=mid;
    17     }
    18     return right;
    19 }
    20 int main()
    21 {
    22     scanf("%d",&n);
    23     for(int i=0;i<n;i++)
    24         scanf("%d",&arr[i]);
    25     for(int i=0;i<n;i++)
    26          printf("%d %d
    ",arr[i],find(arr[i]));
    27 }

    其中判断的结果产生的效果为:找到一个大于x的第一个位置(返回right);找到一个小于等于x的第一个位置(返回left);

    问题1: 为什么不写成 left=mid+1和right=mid-1 ?

      因为有可能arr[mid]已经是极限值。若执行right=mid-1的话,极限值的位置就被跳过了,从而导致出错。

    举个例子:

      设arr[]={0 1 3 4,5}  求找到大于2的第一个位置

      当right=5left=-1;   则mid=2; A[mid]>2;

      因此若r=mid-1=1就导致出错。

    问题2:为什么不写成 While(left!=right) ?

      因为上面的原因我们没用 left=mid+1right=mid-1而是left=mid,right=mid。因此就会出现死循环的情况。

    举个例子:

      arr[]={0,1,3,4}; 求找2的位置时会出现问题

      当left=1right=2时 mid=(left+right)/2=1; arr[mid]<2; 所以left=mid=1

      结果left还是等于1right还是等于2。死循环...

     代码解析:

    原代码中left代表小于等于 x的一方 right代表大于x的一方

    我们每次判断mid是属于left还是属于right来使区间缩小一半;

    leftright相遇时,即left+1=right分界线就在leftright中间

    则从left开始往前小于等于x,right开始往后大于x

    同理其实我们也可以让

    Iff(mid)<x

           left=mid;

    else

           right=mid;

    left代表小于x的一方而right代表大于等于x的一方

    leftright相遇时;

    则从left开始往前小于x,right开始往后大于等于x

     

  • 相关阅读:
    HTB-靶机-Charon
    第一篇Active Directory疑难解答概述(1)
    Outlook Web App 客户端超时设置
    【Troubleshooting Case】Exchange Server 组件状态应用排错?
    【Troubleshooting Case】Unable to delete Exchange database?
    Exchange Server 2007的即将生命周期,您的计划是?
    "the hypervisor is not running" 故障
    Exchange 2016 体系结构
    USB PE
    10 months then free? 10个月,然后自由
  • 原文地址:https://www.cnblogs.com/ashen137/p/10348888.html
Copyright © 2011-2022 走看看