一、定义局部最小的概念。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中任意一个局部最小出现的位置即可。
class Solution {
public:
int getLessIndex(vector<int> arr) {
size_t n = arr.size();
if(n <= 0) return -1;
else if(n == 1) return 0;
else if(arr[0] < arr[1]) return 0;
else if(arr[n-1] < arr[n-2]) return n-1;
int res = get_LessIndex(arr,1,n-2);
return res;
}
int get_LessIndex(vector<int> arr,int left,int right) {
while(left <= right) {
int mid = left + (right-left)/2;
if(arr[mid] < arr[mid-1] && arr[mid] < arr[mid+1]) {
return mid;
}
else if(arr[mid] > arr[mid-1]) {
right = mid - 1;
}
else if(arr[mid] > arr[mid+1]) {
left = mid + 1;
}
}
return -1;
}
};
二、对于一个有序数组arr,再给定一个整数num,请在arr中找到num这个数出现的最左边的位置。
给定一个数组arr及它的大小n,同时给定num。请返回所求位置。若该元素在数组中未出现,请返回-1。
测试样例:
[1,2,3,3,4],5,3
返回:2
//最左的位置,即等于num的第一个数
class LeftMostAppearance {
public:
int findPos(vector<int> arr, int n, int num) {
int res=-1;
int left=0,right=n-1;
int mid=0;
while(left<=right){
mid=left+(right-left)/2;
if(arr[mid]==num){
res=mid;
right=mid-1;
}
else if(arr[mid]>num)
right=mid-1;
else
left=mid+1;
}
return res;
}
};
三、对于一个有序循环数组arr,返回arr中的最小值。有序循环数组是指,有序数组左边任意长度的部分放到右边去,右边的部分拿到左边来。比如数组[1,2,3,3,4],是有序循环数组,[4,1,2,3,3]也是。
给定数组arr及它的大小n,请返回最小值。
测试样例:
[4,1,2,3,3],5
返回:1
class MinValue {
public:
int getMin(vector<int> arr, int n) {
if (n == 0)
return -1;
int left = 0; int right = n - 1;
while (left < right)
{
if (arr[left] < arr[right]) //说明仍然有序,left为最小值
{
return arr[left];
}
if (left == right-1)
{
break;
}
int mid = left + (right - left) / 2;
if (arr[left] > arr[mid]) //最小值在left和mid之间
{
right = mid;
continue;
}
if (arr[right] < arr[mid]) //最小值在mid和right之间
{
left = mid;
continue;
}
while (left < mid)
{
if (arr[left] == arr[mid])
{
left++;
}
else if (arr[left] < arr[mid])
{
return arr[left];
}
else
{
right = mid;
break;
}
}
}
if (arr[left] < arr[right])
return arr[left];
else
return arr[right];
}
};