Suppose you have a long list of numbers, which increases by 1 for each item in the list, ie: 1, 2, 3, 4, 5. Now suppose an element is missing from the list, say, 3. Now the list is: 1, 2, 4, 5. Now consider a list that is millions of elements long. How do you find the missing element without painstakingly iterating through the entire list in O(n) time? Simple: binary search it (with modifications) to achieve O(log(n)) time.
/******************************************************************************* * @file: find.c * @author: Matthew Giassa <matthew@giassa.net> * Test to check for a missing element in a sorted, strictly monotonically * increasing data set. ******************************************************************************/ /******************************************************************************* * Preprocessor directives. ******************************************************************************/ #include <stdio.h> #include <stdlib.h> #include <time.h> #define ARR_SIZE (32) #define MAX_INIT_VAL (100) /******************************************************************************* * Function prototypes. ******************************************************************************/ int find(int* pData, size_t len); /******************************************************************************* * Function definitions. ******************************************************************************/ /*----------------------------------------------------------------------------*/ int main(void) { // Init random seed. srand(time(NULL)); // Populate test array. int rVal = rand() % ARR_SIZE; int arr[ARR_SIZE] = { 0 }; int i = 0, count = rand() % MAX_INIT_VAL; for ( i = 0; i < ARR_SIZE; i++ ) { if ( i == rVal ) { count++; printf("Causing a hole at position %d.\n", i); } arr[i] = count + i; } for ( i = 0; i < ARR_SIZE; i++ ) { printf("%3d ", arr[i]); } printf("\n\n"); // Search for the hole. int iMissing = find(arr, ARR_SIZE); if ( iMissing == (-1) ) { printf("Could not find a hole.\n"); } else { printf("Missing value detected: %d.\n", iMissing); } return 0; } /*----------------------------------------------------------------------------*/ int find(int* pData, size_t len) { int i = 0; int left,middle,right; left = 0; right = len-1; middle = (left+right) / 2; /* Iterate until we converge. */ while (left < right) { if ((pData[middle]-pData[left]) != (middle - left)) { /* An element is missing between the middle and left- * hand size extreme position. */ if ((middle-left) == 1 && (pData[middle]-pData[left] > 1)) { return (pData[middle]-1); } right = middle; } else if ((pData[right]-pData[middle]) != (right-middle)) { /* An element is missing between the middle and right- * hand size extreme position. */ if ((right-middle) == 1 && (pData[right]-pData[middle] > 1)) { return (pData[middle]+1); } left = middle; } else { return -1; } middle = (left+right) / 2; } /* Couldn't find a break in data. Set is strictly monotonically * increasing with no holes. */ return -1; }