LintCode 159. Find Minimum in Rotated Sorted Array (Medium)

LeetCode 153. Find Minimum in Rotated Sorted Array (Medium)

这题看着简单, 但是条件总容易搞错. @_@…

思路是在当前区间有序的时候立即停止, 然后某个点(详见代码)就是答案.

我没有做nums.size() == 0的判断, 因为这种情况应该抛个异常什么的, 给什么int值都可能是有效值(如果nums中的数没有指定范围).

解法1

这个解法要注意一种情况, 就是如果进行R = M - 1之后数组有序了, 最小点应该在R + 1处.

class Solution {
public:
    int findMin(vector<int> &num) {
        int n = num.size();
        int L = 0, R = n - 1;
        while (L <= R) {
            int M = (R - L) / 2 + L;
            if (num[M] > num[R]) {
                L = M + 1;
            } else if (num[M] < num[L]) {
                R = M - 1;
            } else break;
        }
        return R + 1 < n && num[R + 1] < num[L] ? num[R + 1] : num[L];
    }
};

解法1.1

根据上面的分析, 发现那么只进行R = M就可以避免上面的情况了, 于是又写了个更精简的版本.

九章的解法中, target可以换做num[R], 循环条件换成while(L < R), 返回值直接写成num[L], 其实就是这个解法的无break版本, 循环次数会比这个解法多几次, 因为它要一直找到L == R才会结束.

class Solution {
public:
    int findMin(vector<int> &num) {
        int n = num.size();
        int L = 0, R = n - 1;
        while (L < R) {
            int M = (R - L) / 2 + L;
            if (num[M] > num[R]) {
                L = M + 1;
            } else if (num[M] < num[L]) {
                R = M;
            } else break;
        }
        return num[L];
    }
};

解法1.2

这篇博文启发, 判断”是否有序”可以放到while的判断条件中.

class Solution {
public:
    int findMin(vector<int> &num) {
        int n = num.size();
        int L = 0, R = n - 1;
        while (L < R && num[L] > num[R]) {
            int M = (R - L) / 2 + L;
            if (num[M] > num[R]) {
                L = M + 1;
            } else {
                R = M;
            }
        }
        return num[L];
    }
};

时间复杂度: O(logn)

空间复杂度: O(1)