/* 题目: 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转, 输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素, 例如:数组{3,4,5,1,2}。为{1,2,3,4,5}的一个旋转, 该数组但最小值为1. 解题思路: (1):遍历数组,发现最小值,复杂度为 O(n) (2):二分查找,实现复杂度为 O(logN) */ #include <stdio.h> //通过遍历来求解最小值 int findInOrderMin(int numbers[], int length) { if (numbers == NULL || length <= 0) return -1; int num = numbers[0]; for (int i = 1; i < length; i++) { if (num > numbers[i]) num = numbers[i]; } return num; } int findMinNum(int numbers[], int length) { if (numbers == NULL || length <= 0) return -1; int index1 = 0; int index2 = length - 1; int indexMid = index1; while (numbers[index1] >= numbers[index2]) { if (index2 - index1 == 1) //当只有2个元素时,因为前面的大于后面的,所以index2小。 { return numbers[index2]; } indexMid = (index1 + index2)/2; //有两种情况:中间的数字和两边的都相等。 //1——[1,0,1,1,1] 和 2——[1,1,1,0,1] if (numbers[indexMid] == numbers[index2] && numbers[index1] == numbers[index2]) return findInOrderMin(numbers, length); //如果中间数字大于第一个,那么就说明开始位置到中间位置一直递增,这样,最小值在后半段。 if (numbers[indexMid] >= numbers[index1]) index1 = indexMid; //如果中间数字小于最后数字,说明后面一直递增。这样,最小值在前半段。 else if (numbers[indexMid] < numbers[index2]) index2 = indexMid; } return numbers[indexMid]; } int main() { int numbers1[] = {3,4,5,1,2}; int numbers2[] = {1,2,2,2,2}; int numbers3[] = {2,1,2,2,2}; int numbers4[] = {2,2,2,1,2}; printf("%d ", findMinNum(numbers1, 5)); printf("%d ", findMinNum(numbers2, 5)); printf("%d ", findMinNum(numbers3, 5)); printf("%d ", findMinNum(numbers4, 5)); return 0; }