二分搜索(2)

来源:互联网 发布:星星知我心主题曲原唱 编辑:程序博客网 时间:2024/06/06 08:27

一、定义局部最小的概念。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];    }};
原创粉丝点击