题目意思是这样的:给定n个整数,求第i个数右边的距离它最远的比它小的数的下标之差然后再减1。
这里既然是需要知道距离该数最远的下标,可以从右至左扫描一遍,然后按照单调递减的顺序入栈,即只把比栈顶元素小的整数入栈,等于或大于对于后面的数查找比自己小的值没什么意义。然后遇到比栈顶元素大,而又比不大于栈底元素的情况二分搜索就可以了。
1 #include<stdio.h> 2 #define N 100010 3 int a[N],ans[N],stack[N]; 4 int main(void) 5 { 6 int n,i,top=0; 7 scanf("%d",&n); 8 for(i=0; i<n; i++) 9 scanf("%d",&a[i]); 10 for(i=n-1; i>=0; i--) 11 { 12 if(!top||a[i]<=a[stack[top]]) 13 { 14 ans[i]=-1; 15 if(a[i]!=a[stack[top]])//小于栈顶元素或栈为空时入栈 16 stack[++top]=i; 17 } 18 else 19 { 20 if(a[i]>a[stack[1]]) 21 ans[i]=stack[1]-i-1; 22 else 23 { 24 int l,r,mid; 25 for(l=1,r=top,mid=((l+r)>>1); (mid=(l+r)>>1),r-l>1; a[stack[mid]]<a[i]?(r=mid):(l=mid))//记得(r=mid)这里括号不能少,不然无法编译通过 26 ; 27 ans[i]=stack[r]-i-1; 28 } 29 } 30 } 31 for(i=0; i<n; i++) 32 33 printf("%d%c",ans[i],i==n-1?' ':' '); 34 return 0; 35 }