面試題53(二):0到n-1中缺失的數字
阿新 • • 發佈:2018-12-21
一、題目
一個長度為n-1的遞增排序陣列中的所有數字都是唯一的,並且每個數字都在範圍0到n-1之內。在範圍0到n-1的n個數字中有且只有一個數字不在該陣列中,請找出這個數字。
二、關鍵
三、解釋
1.解題思想:基於二分查詢的思想來查詢,如果中間元素的值和下標相等,那麼下一輪只用查詢右半邊,如果中間元素的值和下標不相等,並且它前面一個元素和它的下標相等,則中間這個數字正好是第一個值和下標不相等的元素,它的下標就是在陣列中不存在的數字;如果中間元素的值和下標不相等,並且它前面一個元素和它的下標不相等,則下一輪只需要在左邊查詢。
四、程式碼
#include <cstdio> int GetMissingNumber(const int* numbers, int length) { if(numbers == nullptr || length <= 0) return -1; int left = 0; int right = length - 1; while(left <= right) { int middle = (right + left) >> 1; if(numbers[middle] != middle) { if(middle == 0 || numbers[middle - 1] == middle - 1) //在頭部缺失 return middle; right = middle - 1; } else left = middle + 1; } if(left == length) //在尾部缺失 return length; // 無效的輸入,比如陣列不是按要求排序的, // 或者有數字不在0到n-1範圍之內 return -1; } // ====================測試程式碼==================== void Test(const char* testName, int numbers[], int length, int expected) { if(testName != nullptr) printf("%s begins: ", testName); int result = GetMissingNumber(numbers, length); if(result == expected) printf("Passed.\n"); else printf("Failed.\n"); } // 缺失的是第一個數字0 void Test1() { int numbers[] = { 1, 2, 3, 4, 5 }; int expected = 0; Test("Test1", numbers, sizeof(numbers) / sizeof(int), expected); } // 缺失的是最後一個數字 void Test2() { int numbers[] = { 0, 1, 2, 3, 4 }; int expected = 5; Test("Test2", numbers, sizeof(numbers) / sizeof(int), expected); } // 缺失的是中間某個數字0 void Test3() { int numbers[] = { 0, 1, 2, 4, 5 }; int expected = 3; Test("Test3", numbers, sizeof(numbers) / sizeof(int), expected); } // 陣列中只有一個數字,缺失的是第一個數字0 void Test4() { int numbers[] = { 1 }; int expected = 0; Test("Test4", numbers, sizeof(numbers) / sizeof(int), expected); } // 陣列中只有一個數字,缺失的是最後一個數字1 void Test5() { int numbers[] = { 0 }; int expected = 1; Test("Test5", numbers, sizeof(numbers) / sizeof(int), expected); } // 空陣列 void Test6() { int expected = -1; Test("Test6", nullptr, 0, expected); } int main(int argc, char* argv[]) { Test1(); Test2(); Test3(); Test4(); Test5(); Test6(); return 0; }