[Leetcode]Find Minimum in Rotated Sorted Array I & II

来源:互联网 发布:网站用什么源码好 编辑:程序博客网 时间:2024/04/28 19:24

Find Minimum in Rotated Sorted Array I

Suppose a sorted array is rotated at some pivot unknown to you beforehand.

(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).

Find the minimum element.

You may assume no duplicate exists in the array.


public class Solution {    public int findMin(int[] num) {        if (num == null || num.length == 0) {            return 0;        }                int low = 0;        int high = num.length - 1;                return bst(num, low, high);    }        private int bst(int[] num, int low, int high) {        // This condition is needed to handle the case when array is not        // rotated at all        if (high < low) {            return num[0];        }                // If there is only one element left        if (low == high) {            return num[low];        }                // Find mid        int mid = (low + high) / 2;                // Check if element (mid+1) is minimum element. Consider        // the cases like {3, 4, 5, 1, 2}        if (mid < high && num[mid + 1] < num[mid]) {            return num[mid + 1];        }                // Check if mid itself is minimum element        if (mid > low && num[mid] < num[mid - 1]) {            return num[mid];        }                // Decide whether we need to go to left half or right half        if (num[high] > num[mid]) {            return bst(num, low, mid - 1);        } else {            return bst(num, mid + 1, high);        }    }}

此种解法不直观,要考虑的边界因素太多,一下方法比较直观,而且适合移植到Find Minimum in Rotated Sorted Array II 问题。


这种方法的关键也是用二分查找判断最小值是什么,但是不使用递归。我们用一个min变量来维护当前情况下的最小值,通过比较left元素和mid元素的大小来判断最小值应该在左半边还是右半边。如果num[left] < num[mid]则说明当前最小值在num[left],而全局最小值在右半边,所以另left = mid+ 1之后继续。如果num[left] > num[mid],则说明当前最小值在num[mid],而全局最小值在左半边,所以另right = mid - 1之后继续。这种方法的复杂度为O(logn)。

public int findMin(int[] num) {        int left = 0;        int right = num.length - 1;        int min = num[0];                while (left < right - 1) {            int mid = (left + right) / 2;            if (num[left] < num[mid]) {                min = Math.min(num[left], min);                left = mid + 1;            } else if (num[left] > num[mid]) {                min = Math.min(num[mid], min);                right = mid - 1;            }        }                min = Math.min(num[left], min);        min = Math.min(num[right], min);        return min;    }

 

Find Minimum in Rotated Sorted Array II

II相对于I就是多了一个可以重复的条件,可以重复就使得我们在I中先前的算法不能有效判断num[left]和num[mid]的关系,因此也就不能确定最小值应该在左半边还是右半边。要解决这个问题,就需要跳过相等的值。所以,可以在每次遇到left和mid相等的情况时,另left加1,直到left与mid不想等。这个加1在实现上只是多了一个else语句,但是他另算法复杂度变成了O(n),因为最坏情况下,可能需要一直加到最后才能发现有不同的,或者所有数都是相同的。


public int findMin(int[] num) {        int left = 0;        int right = num.length - 1;        int min = num[0];                while (left < right - 1) {            int mid = (left + right) / 2;            if (num[left] < num[mid]) {                min = Math.min(num[left], min);                left = mid + 1;            } else if (num[left] > num[mid]) {                min = Math.min(num[mid], min);                right = mid - 1;            } else {                left++;            }        }                min = Math.min(num[left], min);        min = Math.min(num[right], min);        return min;    }





0 0