PROBLEM
剑指 Offer 11. 旋转数组的最小数字
难度 简单
MY ANSWER
二分法,交了好几次改的代码很乱。时间复杂度O(log n),空间复杂度O(1)。
class Solution { public: int minArray(vector<int>& numbers) { int min = 0; int x = numbers.size(); int l = 0, r = numbers.size() - 1; if(x == 1) { return numbers[0]; } while(x) { int mid = (l + r) / 2; if(mid == l) { break; } if(numbers[l] == numbers[mid] && numbers[l] == numbers[mid]) { l++; continue; } if(numbers[l] <= numbers[mid] && numbers[mid] <= numbers[r]) { return numbers[l]; } if(numbers[l] <= numbers[mid]) { l = mid; } else { r = mid; } } return numbers[l] < numbers[r] ? numbers[l] : numbers[r]; } };
|
BETTER SOLUTION
同样二分法,代码更简洁易懂,使用low + (high - low) / 2可以防止high+low溢出。high与pivot比较可以避免数组只有两个元素时,pivot和low相等。low = pivot + 1,避免只有两个数的死循环。两数相同时,high减少至不相等后继续二分。
class Solution { public: int minArray(vector<int>& numbers) { int low = 0; int high = numbers.size() - 1; while (low < high) { int pivot = low + (high - low) / 2; if (numbers[pivot] < numbers[high]) { high = pivot; } else if (numbers[pivot] > numbers[high]) { low = pivot + 1; } else { high -= 1; } } return numbers[low]; } };
|
SUMMARY
二分法常考,注意其代码的实现细节。