haluo,我们继续学习…
上节课我们学了怎样在数组中查找一个数,我们样的方法是对半分。
前提条件是是在一个 递增 的数组里进行查询。我再问一下,递增序列和非降序序列有什么区别?
我写两个数组你就知道了。
递增:
1 4 5 7 56 74 88 199
非降序:
1 1 1 2 3 3 4 7 7 16 29 29
通过两个数组我们可以总结出来几个特点:
递增:
①无重复
②每一个数都比前面一个数大
非降序:
①有可能有重复
②整体趋势向上涨(详细情况见数组)
在问一个问题,如果在一个非降序序列中查找x。我们前面的查找程序还生效吗?
现在想想。
我画个图哈
在图中是二分的步骤,好。这么多x,我们选哪个呢??????
这就要用到我们这节课的知识了。
我们在以前的代码上改动。
下界(非《我的世界》的“下界”)
含义:在非降序序列中,x的第一次出现位置。
以前我们在a[m]中找到了x,是不是就直接返回x了,但现在我们要找到第一次出现的位置,就必须往前找x|右边界左移|。
如果<,就要往前面找|左边界右移|。
如果大于也是|右边界左移|。
代码:
#include <bits/stdc++.h>
using namespace std;
int a[10010];
int fd(int a[],int l,int r,int x){
while(l<r){
int m=(l+r)/2;
if(a[m]<x)l=m+1;
else r=m;
}
return l;
}
上界
含义:与下界相反,x最后出现的位置。
以前我们在a[m]中找到了x,是不是就直接返回x了,但现在我们要找到最后一次出现的位置,就必须往后找x|左边界右移|。
如果<,就要往前面找|左边界右移|。
如果大于还没有找到x,就往前找,是|右边界左移|。
代码:
#include <bits/stdc++.h>
using namespace std;
int a[10010];
int fd(int a[],int l,int r,int x){
while(l<r){
int m=(l+r)/2;
if(a[m]<=x)l=m+1;//此处只需加上'='即可
else r=m;
}
return l;
}
小知识:
想要查询x在非降序序列(或递增序列)中出现的次数,只要将上界-下界就可以获取了!