// 面试题11:旋转数组的最小数字 // 题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 // 输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如数组 // {3, 4, 5, 1, 2}为{1, 2, 3, 4, 5}的一个旋转,该数组的最小值为1。 #include <cstdio> #include <exception> int MinInOrder(int* numbers, int index1, int index2); int Min(int* numbers, int length) { //鲁棒性检测 if (numbers == nullptr || length <= 0) throw new std::exception("Invalid parameters"); int index1 = 0; int index2 = length - 1; int indexM = index1; while (numbers[index1] >= numbers[index2]) { if (index2 - index1 == 1) { indexM = index2; break; } indexM = (index1 + index2) / 2; //当三个值相等时, 顺序查找 if (numbers[index1] == numbers[indexM] && numbers[indexM] == numbers[index2]) return MinInOrder(numbers, index1, index2); //缩小范围 if (numbers[index1] <= numbers[indexM]) index1 = indexM; else if (numbers[index2] >= numbers[indexM]) index2 = indexM; } return numbers[indexM]; } int MinInOrder(int* numbers, int index1, int index2) { int indexMin = index1; for (int i = index1 + 1; i <= index2; ++i) { if (numbers[i] < numbers[indexMin]) indexMin = i; } return numbers[indexMin]; }
// ====================测试代码==================== void Test(int* numbers, int length, int expected) { int result = 0; try { result = Min(numbers, length); for (int i = 0; i < length; ++i) printf("%d ", numbers[i]); if (result == expected) printf(" passed "); else printf(" failed "); } catch (...) { if (numbers == nullptr) printf("Test passed. "); else printf("Test failed. "); } } int main(int argc, char* argv[]) { // 典型输入,单调升序的数组的一个旋转 int array1[] = { 3, 4, 5, 1, 2 }; Test(array1, sizeof(array1) / sizeof(int), 1); // 有重复数字,并且重复的数字刚好的最小的数字 int array2[] = { 3, 4, 5, 1, 1, 2 }; Test(array2, sizeof(array2) / sizeof(int), 1); // 有重复数字,但重复的数字不是第一个数字和最后一个数字 int array3[] = { 3, 4, 5, 1, 2, 2 }; Test(array3, sizeof(array3) / sizeof(int), 1); // 有重复的数字,并且重复的数字刚好是第一个数字和最后一个数字 int array4[] = { 1, 0, 1, 1, 1 }; Test(array4, sizeof(array4) / sizeof(int), 0); // 单调升序数组,旋转0个元素,也就是单调升序数组本身 int array5[] = { 1, 2, 3, 4, 5 }; Test(array5, sizeof(array5) / sizeof(int), 1); // 数组中只有一个数字 int array6[] = { 2 }; Test(array6, sizeof(array6) / sizeof(int), 2); // 输入nullptr Test(nullptr, 0, 0); return 0; }
分析:考虑特殊情况。
class Solution { public: int minNumberInRotateArray(vector<int> rotateArray) { if (rotateArray.size() == 0) return 0; int index1 = 0; int index2 = int(rotateArray.size() - 1); int indexM = index1; while(rotateArray[index1] >= rotateArray[index2]) { if (index2 - index1 == 1) { indexM = index2; break; } indexM = (index1 + index2) /2; if (rotateArray[index1] == rotateArray[index2] && rotateArray[index2] == rotateArray[indexM]) return minInOrder(rotateArray, index1, index2); if (rotateArray[index1] <= rotateArray[indexM]) index1 = indexM; if (rotateArray[index2] >= rotateArray[indexM]) index2 = indexM; } return rotateArray[indexM]; } int minInOrder(vector<int> rotateArray, int index1, int index2) { int indexMin = index1; for (int i = index1 + 1; i <= index2; ++i) { if (rotateArray[i] < rotateArray[indexMin]) indexMin = i; } return rotateArray[indexMin]; } };