单调有序数组被循环右移k位后

题目描述:
单调有序数组被循环右移k 位后找最小值时间复杂度的要求log N

一个有序数组循环右移n位,找到右移后该数组的最小值,数组中可能包含重复元素。

以最小值的位置分类,可以分成两种,一种是在中间偏左,一种实在中间偏右。

上图表示最小值在中间偏左的情况,由于原数组是递增序列,所以nums[middle : right]是递增的,即nums[middle]<nums[right],此时可以确定将结果缩小到nums[left : middle]这个范围内


同理,当最小值在中间偏右时,nums[left : middle]是递增的,根据大小关系可知nums[middle]>nums[right],此时可以确定将结果缩小到nums[middle+1 : right]这个范围内

而当nums[middle]==nums[right]时,无法确定最小值的位置,此时可以做的事情是尽量缩小范围,又因为知道nums[middle]和nums[right]值相同,所以nums[right]可以抛弃,即将结果范围缩小到nums[left : right-1]重新计算(注意,目的是找最小值而不是第一个最小值的位置,所以就算nums[right]是第一个最小值也无关紧要)

show code:


    public static void main(String[] args) {
        int[] arr = new int[]{7, 8, 9, 1, 1, 2, 3, 4, 5, 6};// 789123456
        System.out.println(findMin(arr));
    }

    public static int findMin(int[] nums) {
        int n = nums.length;
        int left = 0;
        int right = n - 1;
        while (left < right) {
            int middle = left + (right - left) / 2;
            if (nums[middle] < nums[right]) {
                right = middle;
            } else if (nums[middle] > nums[right]) {
                left = middle + 1;
            } else {
                right = right - 1;
            }
        }
        return nums[left];
    }
//output
1
# 算法 

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×