【面试题8】旋转数组的最小数字
【题目描述】
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增序列的数组的一个旋转,输出旋转数组的最小元素。例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
【解决方案】
1. 使用二分查找,画图思考;
2. 考虑旋转数组的数量为0时(即为排好序的数组本身)特殊情况的处理;
3. 考虑{1,0,1,1,1}和{1,1,1,0,1}的情况,当first,mid,end所指数值相同时,无法判断最小数位于前后哪个区间,需要使用顺序查找;
我的代码实现,仅供参考:
1 public static int Min(int[] arr) 2 { 3 int start = 0; 4 int end = arr.Length - 1; 5 6 //针对旋转数组的数量为0时(即为排好序的数组本身)特殊情况的处理 7 int mid = start; 8 9 while (arr[start] >= arr[end]) 10 { 11 if (end - start == 1) 12 { 13 mid = end; 14 break; 15 } 16 17 mid = (start + end) / 2; 18 19 //当first,mid,end所指数值相同时,无法判断最小数位于前后哪个区间,需要使用顺序查找 20 if (arr[start] == arr[mid] && arr[mid] == arr[end]) 21 { 22 return MinInOrder(arr, start, end); 23 } 24 25 if (arr[mid] >= arr[start]) 26 { 27 start = mid; 28 } 29 else if (arr[mid] <= arr[end]) 30 { 31 end = mid; 32 } 33 } 34 35 return arr[mid]; 36 } 37 38 public static int MinInOrder(int[] arr, int first, int end) 39 { 40 int min = arr[end]; 41 for (int i = first; i < end; i++) 42 { 43 if (arr[i] < min) 44 min = arr[i]; 45 } 46 return min; 47 }