【题11 旋转数组的最小数字】

【题11 旋转数组的最小数字】
【题目】
把一个数组最开始的若干个元素都搬到数组的末尾,称之为数组的旋转。
输入一个递增排序的数组的一个旋转,输出的旋转数组的最小元素。
例如:数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1.
分析:
(1) 两个指针,分别指向第一个元素和最后一个元素,(第一个元素大于等于第二个元素(有特例))
(2) 找到中间元素,如果中间元素位于前面递增子数组,则中间元素大于等于第二个指针指向的元素,此时最小元素位于该中间元素的后面,查找范围缩小。
(3) 如果中间元素位于后面的递增子数组,中间元素小于等于第二个指针指向的元素,此时最小元素位于该中间元素前面,查找范围缩小。
(4) 最终会指向两个相邻元素,而第二个指针指向的刚好是最小元素,循环结束

在这里插入图片描述
注:
由于把递增排序数组前面的若干个数字搬到数组的后面,所以第一个数字总大于等于最后一个数。
特例:
如果把排序数组的前面的0个元素搬到最后面,即排序数组本身,这仍是数组的一个旋转,代码需要支持这种情况。此时数组中的第一个数字就是最小的数字,可直接返回。
分析:
仔细分析下标index1和index2(对应P1和P2)当这两个数字和中间数字都相同时,如图。
在这里插入图片描述
在这里插入图片描述

数组{1,0,1,1}和{1,1,1,0,1}都可以看成递增排序数组{0,1,1,1,1}的旋转。
这两种情况,第一个指针和第二个指针的数字都是1,并且两个指针中间的数字也是1,这三个数字相同,无法判断中间数字是位于前面数组还是后面数组,无法移动指针缩小范围,不得不采用顺序查找的方法。

实现

package ti11;

//题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
//输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如数组
//{3, 4, 5, 1, 2}为{1, 2, 3, 4, 5}的一个旋转,该数组的最小值为1。

public class MinNumberInRotatedArray {
 public int minNumberInRotateArray(int[] array) {
     if (array == null || array.length <= 0) // 空数组或null时返回0
         return 0;
     int low = 0;
     int high = array.length - 1;
     int mid = (low + high) / 2;
     //升序数组
     if (array[low] < array[high])
         return array[low];
     //中间数字与首尾数字相等
     if (array[mid] == array[high] && array[mid] == array[low]) {
         for (int i = 1; i <= high; i++) {
             if (array[i] < array[i - 1])
                 return array[i];
         }
         return array[low];
     }
     //正常情况
     while (low < high) {
         if (high - low == 1)
             break;
         mid = (low + high) / 2;
         if (array[mid] <= array[high])
             high = mid;
         if (array[mid] > array[high])
             low = mid;
     }
     return array[high]; // 别错写成了return high; !!
 }

 // =======测试代码======
 public void test1() {
     int[] array = null;
     System.out.println("test1:" + minNumberInRotateArray(array));
 }

 public void test2() {
     int[] array = {};
     System.out.println("test2:" + minNumberInRotateArray(array));
 }

 public void test3() {
     int[] array = { 1 };
     System.out.println("test3:" + minNumberInRotateArray(array));
 }

 public void test4() {
     int[] array = { 1, 2, 3, 4, 5, 6 };
     System.out.println("test4:" + minNumberInRotateArray(array));
 }

 public void test5() {
     int[] array = { 2, 2, 2, 2, 1, 2 };
     System.out.println("test5:" + minNumberInRotateArray(array));
 }

 public void test6() {
     int[] array = { 2, 1, 2, 2, 2, 2 };
     System.out.println("test6:" + minNumberInRotateArray(array));
 }

 public void test7() {
     int[] array = { 6, 6, 8, 9, 10, 1, 2, 2, 3, 3, 4, 5, 6 };
     System.out.println("test7:" + minNumberInRotateArray(array));
 }

 public static void main(String[] args) {
     MinNumberInRotatedArray demo = new MinNumberInRotatedArray();
     demo.test1();
     demo.test2();
     demo.test3();
     demo.test4();
     demo.test5();
     demo.test6();
     demo.test7();
 }
}

参考:
1.《剑指offer》
2.https://www.cnblogs.com/yongh/p/9649169.html

猜你喜欢

转载自blog.csdn.net/weixin_39795049/article/details/86135741