【剑指offer】面试题8----旋转数组的最小数字
程序员文章站
2022-06-17 19:46:22
...
1、题目
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。
例如数组{8,9,1,2,3,4,5,6,7}是{1,2,3,4,5,6,7,8,9}的一个旋转,该数组的最小值为1。
2、解题思路:
首先根据题目的要求来看,旋转后的该数组可以看成两部分,两个部分各自有序,且前面一部分的值始终大于后面部分的值,该数组的最小值就为后一部分的第一个元素。
设置两个标记,一个标记指向数组起始位置-first,一个标记指向数组末尾位置=last。
接着找到数组的中间位置,如果中间位置的值大于first,就令first=mid;否则令last=mid;直到结束循环条件为止。
3、源码
/*
旋转数组的最小数字
*/
#include<stdio.h>
#include<iostream>
using namespace std;
int MinInOrder(int arr[], int left, int right){
int min = arr[left];
for (size_t i = left + 1; i <= right; ++i){
if (arr[i] < min)
min = arr[i];
}
return min;
}
int Min(int arr[], int len){
if (NULL == arr || len <= 0){
throw new exception("Invalid parameters");
}
int first = 0;
int last = len - 1;
int mid = first;
while (arr[first] >= arr[last]){
if (last - first == 1){
//此时两个标记相邻,说明最小的元素就是两个相邻元素靠后的那一个
mid = last;
break;
}
mid = (first + last) / 2;
/*
特殊情况:
如果下标first,last,mid所指向的元素相等
则此时应采取顺序查找的方法
*/
if (arr[first] == arr[last] && arr[first] == arr[mid])
return MinInOrder(arr, first, last);
if (arr[mid] >= arr[first])
first=mid;
if (arr[mid] <= arr[last])
last = mid;
}
return arr[mid];
}
void Print(int arr[], int len){
for (size_t i = 0; i < len; i++){
cout << arr[i] << " ";
}
cout << endl;
}
int main(){
int arr[] = { 8, 9, 1, 2, 3, 4, 5, 6, 7 };
int len = sizeof(arr) / sizeof(arr[0]);
Print(arr, len);
int ret = Min(arr, len);
cout << "该数组最小的元素为:" << ret << endl;
}
4、结果
上一篇: 剑指offer 旋转数组的最小数字
下一篇: leetcode21合并两个有序链表
推荐阅读
-
剑指offer28:找出数组中超过一半的数字。
-
【剑指 Offer-python】 03. 数组中重复的数字
-
【剑指Offer】最小的K个数:[数组][高级算法]
-
剑指offer 56 数组中数字出现的次数 lintcode 82. 落单的数、83. 落单的数 II、84. 落单的数 III
-
【剑指offer】面试题56(1):数组中只出现一次的两个数字
-
剑指offer:数组中只出现一次的两个数字(java版)
-
剑指offer 面试题56 python版+解析:数组中只出现一次的两个数字,数组中唯一只出现一次的数字
-
剑指offer第二版-56.数组中只出现一次的两个数字
-
【算法分享】剑指offer56-数组中只出现一次的两个数字
-
剑指 Offer 56 - I. 数组中只出现一次的两个数字