2019-03-23 旋转数组的最小数字--二分查找

2019-03-24  本文已影响0人  longxingxiu

题目描述

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

解题思路和算法复杂度请看方法注释。

package cn.mayday.arroroffer.title6;

/**
 * @description: 旋转数组的最小数字
 * @author: mayday
 * @date: 2019/3/24 10:03
 * @version: 1.0
 */
public class Solution {

    public static void main(String[] args) {
        System.out.println(1 == new Solution().minNumberInRotateArray(new int[]{3, 4, 5, 1, 2})); // true

    }

    /**
     * 方法1:直接遍历
     * 找到第一个比前面一个小的元素就能证明这个元素时最小的,时间复杂度 o(n)
     *
     * @param array
     * @return
     */
    public int minNumberInRotateArray1(int[] array) {
        if (null == array || array.length == 0) {
            return 0;
        }
        int temp = array[0];
        for (int i = 1; i < array.length; i++) {
            if (array[i] < temp) {
                // 找到第一个比前面一个小的元素,立刻返回结果
                return array[i];
            } else {
                temp = array[i];
            }
        }
        return temp;
    }

    /**
     * 方法2:二分查找
     * <p>
     * 有序数组中查找最小元素,二分查找法。时间复杂度(O(lgn))
     *
     * @param array
     * @return
     */
    public int minNumberInRotateArray(int[] array) {
        if (null == array || array.length == 0) {
            return 0;
        }
        int left = 0;
        int right = array.length - 1;
        if (array[left] < array[right]){
            // 正常顺序直接查找
            return array[left];
        }
        while (left < right) {
            // 二分查找
            int middle = left + (right - left) / 2;
            // 如果只剩1-2个元素
            if (middle == left || middle == right) {
                break;
            }
            // 如果middle元素比最左边的小,可以缩小范围,middle右边的数据都可以丢掉
            // 如果middle元素比最右边的小,可以缩小范围,middle右边的数据都可以丢掉
            // 如果middle元素比最右边的大,可以缩小范围,middle左边以及middle的数据都可以丢掉
            if (array[middle] < array[left]) {
                right = middle;
            } else if (array[middle] < array[right]) {
                right = middle;
            } else if (array[middle] > array[right]) {
                left = middle + 1;
            }
        }
        return array[left] > array[right] ? array[right] : array[left];
    }
}

上一篇下一篇

猜你喜欢

热点阅读