定义局部最小的概念。arr长度为1时,arr[0]是局部最小。arr的长度为N(N>1)时,如果arr[0]<arr[1],那么arr[0]是局部最小;如果arr[N-1]<arr[N-2],那么arr[N-1]是局部最小;如果0<i<N-1,既有arr[i]<arr[i-1]又有arr[i]<arr[i+1],那么arr[i]是局部最小。
给定无序数组arr,已知arr中任意两个相邻的数都不相等,写一个函数,只需返回arr中任意一个局部最小出现的位置即可。
分析:
如果arr[0]<arr[1],那么arr[0]是局部最小;--返回0
如果arr[N-1]<arr[N-2],那么arr[N-1]是局部最小;--返回1
如果arr[0]和arr[N-1]都不是,那么left = 1, right = N+2, mid =(left+right)/2
若arr[mid] < arr[mid+1]且 arr[mid]<arr[mid-1],则返回mid
否则必有arr[mid] < arr[mid+1]或arr[mid]<arr[mid-1],假设arr[mid] < arr[mid+1]
由于,arr[0]<arr[1], arr[mid] < arr[mid+1] 则可知,arr[1]到arr[mid]比存在一个局部最小,如此反复迭代。时间复杂度O(lgn),比遍历的O(n)要好。
1 class Solution 2 { 3 public: 4 int getLessIndex(vector<int> arr) 5 { 6 if(arr.size() == 0) 7 return -1; 8 if(arr.size() == 1) 9 return 0; 10 if(arr[0] < arr[1]) 11 return 0; 12 13 int size = arr.size(); 14 if(arr[size - 1] < arr[size - 2]) 15 return size - 1; 16 17 int low = 1; 18 int high = size - 2; 19 int mid; 20 21 while(low < high) 22 { 23 mid = (low + high)/2; 24 if(arr[mid] > arr[mid+1]) 25 { 26 low = mid+1; 27 } 28 else if(arr[mid] > arr[mid-1]) 29 { 30 high = mid-1; 31 } 32 else 33 return mid; 34 } 35 return low; 36 37 } 38 };
思路二:
int find(int arr[],int start, int ed){ int mid = (start + end) / 2; if (mid - 2 < 0 && mid + 1 >= arr.length) return -1;//已知a[0]>=a[1] 并且 a[n]>=a[n-1] if (arr[mid - 2] > arr[mid - 1] && arr[mid - 1] < arr[mid]) return arr[mid - 1]; if (arr[mid - 1] > arr[mid - 2]) return findLocalMinima(arr, start, mid); else return findLocalMinima(arr, mid, end); }
参考:http://www.cnblogs.com/diegodu/p/4589781.html
http://blog.csdn.net/sentimental_dog/article/details/51123081