给定一个整性数组,如果一个值不大于它前面与后面的元素,即a<=a[i-1] && a <=a[i + 1](如果是头或者尾,则只看一边),则a叫做一个局部最小值。求出这个数组一个最小值的下标或值。(只求一个即可)
直接2分 可以使复杂度成为:O(logN)
区间 a[from..to] 可以这样想:
首先,任意一段数组都有局部最小值,我们2分的话,一定能找到一个解。
如果a[from] <= a[from + 1] 则 a[from]就是一个所求
如果a[to - 1] >= a[to] 则a[to]就是一个所求
否则 有a[from] > a[from + 1] a[to - 1] < a[to] (*)
我们看mid = (from + to) / 2
(1) a[mid] > a[mid - 1] 则 这个情况 和 (*) 的条件比较一样 所以可以在from..mid-1 里面找
(2) 否则 a[mid] > a[mid + 1] 则 这个情况 也类似 和(*) 可以在mid+1..to里面找
(3) 否则 有 a[mid - 1] >= a[mid] a[mid + 1] >= a[mid] 则a[mid]就是一个所求
主要感受一下二分的思想,将复杂度降低。
#include<stdio.h> int findlocalmin(int *a,int from,int to); main() { int a[100],i,len,localmin; scanf("%d",&len); for(i=0; i<len; i++) scanf("%d",&a[i]); localmin=findlocalmin(a,0,len-1); printf("%d\n",localmin); } int findlocalmin(int *a,int begin,int end) { if(end-begin<=1) return (a[begin]<a[end])?a[begin]:a[end]; int mid=(begin+end)>>2; if(a[mid]>a[mid-1]) return findlocalmin(a,begin,mid-1); if(a[mid]>a[mid+1]) return findlocalmin(a,mid+1,end); return a[mid]; }