剑指Offe [06] 旋转数组的最小数字

来源:互联网 发布:怎么知道我的网络 编辑:程序博客网 时间:2024/06/05 02:06

旋转数组的最小数字 : 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组 {3,4,5,1,2} 为 {1,2,3,4,5} 的一个旋转,该数组的最小值为 1 。 NOTE:给出的所有元素都大于 0,若数组大小为 0,请返回 0。

  • 注意点:

    • 查找一个有序数组中的元素时,第一时间想到的查找算法应该是折半查找,这种查找算法的时间复杂度为 O(logN)
  • 思路:

    • 设定指向数组 index1 = 0 index2 = length-1 的两个指针
    • 想找到最小的,就要找到递减的那个序列
      1. 若中间元素大于最开始元素,那么最开始元素到中间元素是递增的,要想找到递减的序列,那么最小元素一定在数组右边
      2. 若中间元素小于最开始元素,那么最小元素一定在数组左边
      3. 若中间元素等于开始元素,并等于结尾元素,这样我们就无法判断最小元素在左边还是右边(如:10111,11101),这种情况就只能顺序遍历了
package A06旋转数组的最小数字;public class Solution {    public int minNumberInRotateArray(int[] array) {        if (array.length == 0) {            return 0;        }        // index1 指向第一个递增子序列,index2 指向第二个递增子序列        int index1 = 0;        int index2 = array.length - 1;        int mid = index1;        while (array[index1] >= array[index2]) {            // 指针距离为1,说明index1 走向第一个递增序列的结尾,index2 走向第二个递增序列的开头            if (index2 - index1 == 1) {                return array[index2];            }            mid = (index1 + index2) / 2;            // 若三者相等,只能按照顺序查找            if (array[index1] == array[mid] && array[mid] == array[index2]) {                return preOrder(array, index1, index2);            }            // 最小数字在 右边            if (array[mid] >= array[index1]) {                index1 = mid;            } else if (array[mid] <= array[index2]) {                // 最小数字在 左边                index2 = mid;            }        }        return array[mid];    }    public int preOrder(int[] array, int start, int end) {        int result = array[start];        for (int i = 1; i < array.length; i++) {            if (result > array[i]) {                result = array[i];            }        }        return result;    }    public static void main(String[] args) {        Solution solution = new Solution();        int[] array = {1, 0, 1, 1, 1};        System.out.println(solution.minNumberInRotateArray(array));    }}
原创粉丝点击