📜  查找最小缺失数的 C++ 程序

📅  最后修改于: 2022-05-13 01:55:32.898000             🧑  作者: Mango

查找最小缺失数的 C++ 程序

给定一个由 n 个不同整数组成的排序数组,其中每个整数的范围为 0 到 m-1 且 m > n。找到数组中缺少的最小数字。

例子

Input: {0, 1, 2, 6, 9}, n = 5, m = 10 
Output: 3

Input: {4, 5, 10, 11}, n = 4, m = 12 
Output: 0

Input: {0, 1, 2, 3}, n = 4, m = 5 
Output: 4

Input: {0, 1, 2, 3, 4, 5, 6, 7, 10}, n = 9, m = 11 
Output: 8

感谢 Ravichandra 提出以下两种方法。

方法一(使用二分查找
对于 i = 0 到 m-1,对数组中的 i 进行二分搜索。如果数组中不存在 i,则返回 i。
时间复杂度:O(m log n)

方法2(线性搜索
如果 arr[0] 不为 0,则返回 0。否则从索引 0 开始遍历输入数组,对于每对元素 a[i] 和 a[i+1],求它们之间的差。如果差值大于 1,则 a[i]+1 是缺失的数字。
时间复杂度:O(n)

方法 3(使用修改后的二进制搜索)
感谢 yasein 和Jams提出这种方法。
在标准的二分搜索过程中,将要搜索的元素与中间元素进行比较,并根据比较结果决定是结束搜索还是去左半边或右半边。
在这种方法中,我们修改了标准的二分搜索算法,将中间元素与其索引进行比较,并在此比较的基础上做出决策。

  • 如果第一个元素与其索引不同,则返回第一个索引
  • 否则得到中间索引说中间
    • 如果 arr[mid] 大于 mid 则所需元素位于左半部分。
    • 否则所需的元素位于右半部分。
C++
// C++ program to find the smallest elements
// missing in a sorted array.
#include
using namespace std;
  
int findFirstMissing(int array[], 
                    int start, int end)
{
    if (start > end)
        return end + 1;
  
    if (start != array[start])
        return start;
  
    int mid = (start + end) / 2;
  
    // Left half has all elements 
    // from 0 to mid
    if (array[mid] == mid)
        return findFirstMissing(array, 
                            mid+1, end);
  
    return findFirstMissing(array, start, mid);
}
  
// Driver code
int main()
{
    int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 10};
    int n = sizeof(arr)/sizeof(arr[0]);
    cout << "Smallest missing element is " <<
        findFirstMissing(arr, 0, n-1) << endl;
}
  
// This code is contributed by
// Shivi_Aggarwal


C++
//C++ program for the above approach
#include 
  
using namespace std;
  
// Program to find missing element
int findFirstMissing(vector arr , int start ,
                        int  end,int first)
{
  
  if (start < end)
  {
    int mid = (start + end) / 2;
  
    /** Index matches with value
      at that index, means missing
      element cannot be upto that po*/
    if (arr[mid] != mid+first)
      return findFirstMissing(arr, start,
                                 mid , first);
    else
      return findFirstMissing(arr, mid + 1,
                                 end , first);
  }
  return start + first;
  
}
  
// Program to find Smallest
// Missing in Sorted Array
int findSmallestMissinginSortedArray(vector arr)
{
    
  // Check if 0 is missing
  // in the array
  if(arr[0] != 0)
    return 0;
  
  // Check is all numbers 0 to n - 1
  // are present in array
  if(arr[arr.size() - 1] == arr.size() - 1)
    return arr.size();
  
  int first = arr[0];
  
  return findFirstMissing(arr, 0, arr.size() - 1, first);
}
  
  
// Driver program to test the above function
int main()
{
    vector arr = {0, 1, 2, 3, 4, 5, 7};
    int n = arr.size();
  
    // Function Call
    cout<<"First Missing element is : "<


输出
Smallest missing element is 8

注意:如果数组中有重复元素,此方法不起作用。
时间复杂度: O(Logn)

另一种方法:这个想法是使用递归二进制搜索来找到最小的缺失数。下面是借助步骤的插图:

  • 如果数组的第一个元素不为 0,则最小的缺失数为 0。
  • 如果数组的最后一个元素是 N-1,那么最小的缺失数是 N。
  • 否则,从第一个和最后一个索引中找到中间元素,并检查中间元素是否等于所需元素。即第一+middle_index。
    • 如果中间元素是想要的元素,那么最小的缺失元素在中间的右搜索空间中。
    • 否则,最小的缺失数在中间的左侧搜索空间中。

下面是上述方法的实现:

C++

//C++ program for the above approach
#include 
  
using namespace std;
  
// Program to find missing element
int findFirstMissing(vector arr , int start ,
                        int  end,int first)
{
  
  if (start < end)
  {
    int mid = (start + end) / 2;
  
    /** Index matches with value
      at that index, means missing
      element cannot be upto that po*/
    if (arr[mid] != mid+first)
      return findFirstMissing(arr, start,
                                 mid , first);
    else
      return findFirstMissing(arr, mid + 1,
                                 end , first);
  }
  return start + first;
  
}
  
// Program to find Smallest
// Missing in Sorted Array
int findSmallestMissinginSortedArray(vector arr)
{
    
  // Check if 0 is missing
  // in the array
  if(arr[0] != 0)
    return 0;
  
  // Check is all numbers 0 to n - 1
  // are present in array
  if(arr[arr.size() - 1] == arr.size() - 1)
    return arr.size();
  
  int first = arr[0];
  
  return findFirstMissing(arr, 0, arr.size() - 1, first);
}
  
  
// Driver program to test the above function
int main()
{
    vector arr = {0, 1, 2, 3, 4, 5, 7};
    int n = arr.size();
  
    // Function Call
    cout<<"First Missing element is : "<
输出
First Missing element is : 6

时间复杂度: O(Logn)

有关详细信息,请参阅有关查找最小缺失数字的完整文章!