{面试题8: 旋转数组的最小数字}
From 剑指Offer 何海涛 著
int findMin(vector<int>& nums) { if(nums.empty()) { return 0; } int left = 0; int right = nums.size()-1; while(left < right && nums[left] >= nums[right]) { int middle = (left+right) >> 1;
// 当三个值均相等时, 无法判断最小值位于哪个半区间, 只能顺序遍历 if(nums[left] == nums[middle] && nums[left] == nums[right]) { int min = nums[left]; for(int i=left+1; i<=right; i++) { if(min > nums[i]) { min = nums[i]; } } return min; } if(nums[middle] < nums[left]) { right = middle; } else { left = middle+1; } } return nums[left]; }
测试集:
void test(const int array[], int length, int expected) { std::cout << std::boolalpha << (findMin(array, length) == expected) << std::endl; } int main(int argc, char* argv[]) { int array1[] = {3, 4, 5, 1, 2}; int array2[] = {3, 4, 5, 1, 1, 2}; int array3[] = {3, 4, 5, 1, 2, 2}; int array4[] = {1, 0, 1, 1, 1,}; int array5[] = {1, 2, 3, 4, 5}; int array6[] = {2}; int array7[] = {3, 1, 3}; try { test(NULL, 5, 0); } catch (std::exception& e) { std::cout << "true" << std::endl; } try { test(array1, 0, 0); } catch (std::exception& e) { std::cout << "true" << std::endl; } test(array1, 5, 1); test(array2, 6, 1); test(array3, 6, 1); test(array4, 5, 0); test(array5, 5, 1); test(array6, 1, 2); test(array7, 3, 1); return 0; }