把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3,4,5,1,2}为数组{1, 2,3, 4, 5}的一个旋转,该数组的最小值为1。
创新互联是专业的剑川网站建设公司,剑川接单;提供网站设计、成都网站制作,网页设计,网站设计,建网站,PHP网站建设等专业做网站服务;采用PHP框架,可快速的进行剑川网站开发网页制作和功能扩展;专业做搜索引擎喜爱的网站,专业的做网站团队,希望更多企业前来合作!当然了,将数组遍历一遍肯定能找出最小值,但其时间复杂度为O(N),效率是最低的,因此,应该有一种更高效的解决办法。
因为原数组是递增的,因此数组的第一个元素一定是最小值,而旋转之后,其最小值就会成为旋转的分界点,因此,查找一个旋转之后数组的最小值可以变成查找一个旋转数组的旋转点。而我们仍然可以发现,在旋转点之前的序列是递增有序的,而在旋转点之后的序列也是递增有序的,因此可以这样判断:
取数组的中间值;
如果中间值比最左值大且比最右值小,那么这个数组就是递增数组旋转幅度为0,最小值就为数组第一个值,直接返回;
如果中间值比左边一个数小且比右边一个数小,那么中间值就为旋转点也就是最小值,直接返回;
如果中间值比最左值大且比最右值大,那么中间值往左一定是递增有序的,而旋转点一定在中间值往右,将范围缩到中间值右半边重新从第1步开始;
如果中间值比最左值小且比最右值小,那么中间值往右一定是递增有序的,而旋转点一定在中间值往左,将范围缩到中间值左半边重新从第1步开始;
上面的分析其实是相当于在用二分查找来做,这样就将时间复杂度降为了O(lgN),下面用代码来实现:
#include <iostream> #include <assert.h> using namespace std; int find_min_num(const int *arr, size_t n) { assert(arr && n); int left = 0; int right = n-1; int mid = (right-left)/2; while(left < right) { if((arr[left] <= arr[mid]) && (arr[mid] <= arr[right])) { break;//当数组区间为递增时,最小值就为最左值 } else if((arr[mid-1] > arr[mid]) && (arr[mid+1] > arr[mid])) { return arr[mid];//当取到的中间值就为旋转点时,最小值就为中间值 } else if((arr[left] <= arr[mid]) && (arr[mid] >= arr[right])) { left = mid + 1;//当中间值比左边大且比右边大时 } else { right = mid - 1;//除去上面的三种情况就只剩一种了,那就是中间值比左线小且比右边小 } mid = (right-left)/2 + left; } return arr[left]; } int main() { int arr[] = {8, 9, 2, 3, 4, 5, 6, 7}; int ret = find_min_num(arr, sizeof(arr)/sizeof(arr[0])); cout<<"the min number is: "<<ret<<endl; return 0; }
运行程序,输出结果为2;
可以将数组设定为不同的情况来检验。
《完》
创新互联www.cdcxhl.cn,专业提供香港、美国云服务器,动态BGP最优骨干路由自动选择,持续稳定高效的网络助力业务部署。公司持有工信部办法的idc、isp许可证, 机房独有T级流量清洗系统配攻击溯源,准确进行流量调度,确保服务器高可用性。佳节活动现已开启,新人活动云服务器买多久送多久。
网页标题:输出一个为递增排序数组的旋转数组中的最小元素——8-创新互联
文章网址:https://www.cdcxhl.com/article14/hpide.html
成都网站建设公司_创新互联,为您提供外贸网站建设、营销型网站建设、网站建设、手机网站建设、网页设计公司、商城网站
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联