剑指Offer(Java实现):旋转数组的最小数字

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

解题
用两个指针,一个指向第一个,一个指向最后一个,中间的数字大于第一个就让第一个的指针指到中间的数字(这个时候数组就剩一半了),中间的小于最后一个就让最后一个指向中间的数字。最小的数字肯定是中间那个数字的下一个,最后两个指针是挨着的一个指向中间的数字,一个指向下一个,返回指向下一个的就可以了。要是数组是顺序的就直接返回第一个指针指向的数字。要是三个指针指向的数字相等就按照顺序排序的方法找到最小值。

代码

public class T11 {

    public static void main(String[] args) throws Exception {
        int[] nums={3,4,5,1,2};
        System.out.println(findMin(nums,5));
        int[] nums1={1,2,3,4,5};
        System.out.println(findMin(nums1,5));
    }
    public static int findMin(int nums[],int length) throws Exception {
        //数组为空
        if (nums == null || nums.length < 0) {
            throw new Exception("空数组");
        }

        int left = 0;
        int right = length - 1;
        int indexMid = left;//如果是顺序数组,则直接返回第一个即可
        while (nums[left] >= nums[right]) {
            if (right - left == 1) {
                indexMid = right;
                break;
            }

            indexMid = (left + right) / 2;

            //如果数组特殊,left,right,indexMid指向的数字都相等,就用顺序查找
            if (nums[left] == nums[right] && nums[indexMid] == nums[left])
                return MinInOrder(nums, left, right);
            //较为常见的数组,则用类似二分查找的思路
            if (nums[left] <= nums[indexMid])
                left = indexMid;
            if (nums[right] >= nums[indexMid])
                right = indexMid;
        }
        return nums[indexMid];
    }


    private static int MinInOrder(int[] nums, int left, int right) {
        int result = nums[left];
        for(int i = left+1;i<=right;i++){
            if(result>nums[i])
                result = nums[i];
        }
        return result;
    }
}
发布了49 篇原创文章 · 获赞 4 · 访问量 2515

猜你喜欢

转载自blog.csdn.net/weixin_42040292/article/details/104035006