【问题标题】:How can I find minimum and unique element of array in c++?如何在 C++ 中找到数组的最小和唯一元素?
【发布时间】:2020-03-13 01:04:52
【问题描述】:

我有一个大小为 N 的数组(数字)。我需要找到唯一的最小元素,所以如果arr[5] ={1,2,3,1,2},答案是 3。 我用下面的代码试过了:

Int n = sizeof(arr)/sizeof(arr[0]);
sort(arr,arr + n);
for(int i = 0;i<N;i++){
     for(int j = 0;j<N;j++){
        if(arr[i] == arr[j]){
           remove(arr,arr+n,i);
           remove(arr,arr+n,j);
        }
    }
}

但问题是,这只有在我有 2 个相同的 arr 元素时才有效。我可以创建相同数量的条件,但我可以有 3 个或 4 个或 1000 个,所以这会很奇怪。那么有什么更优雅的方法来做到这一点呢?提前谢谢你。

【问题讨论】:

  • 如果数组已排序,我假设它来自您的 sort 调用,那么您不需要像这样的第二个内部循环。可以比较arr[i]arr[i+1],如果相等则继续,否则arr[i]是最小值。
  • 是的,但是我可以拥有 1000 个元素,这些元素与 arr[ i ] 相同。
  • 您也可以使用 HashSet,将所有值存储在其中,如果您看到重复则删除该值,然后在处理所有值后,您可以获得唯一的最小值,这样您将拥有一个O(N) 的时间复杂度。
  • 使用std::set,称为firststd::unordered_set,称为many。遍历数组。第一次看到一个值时,它进入first,如果再次看到它,它将从first 中删除并进入many。当循环迭代完成时,first 中的第一个值就是您的答案。很简单。

标签: c++ arrays sorting unique min


【解决方案1】:

试试这个代码,它使用了一个无序的地图

int m = 2147483647;
    int int_array[] = { 1,2,3,3,1,6,7,7,9 };
    unordered_map<int, int> map;
    for (int i = 0; i < sizeof(int_array) / sizeof(int_array[0]); i++) {
        map[int_array[i]] = map[int_array[i]] + 1;
    }
    unordered_map<int, int>::iterator itr;

    for (itr = map.begin(); itr != map.end(); itr++)
    {
        if (itr->second == 1) {
            if (itr->first < m) {
                m = itr->first;
            }
        }
    }
    printf("minimum unique is %d", m);

【讨论】:

    【解决方案2】:

    对数组排序后,您可以计算重复成员的数量,如果成员是唯一的,则其计数为零:

    int main()
    {
        int arr[] = { 1, 2, 1, 3, 4, 1, 2 };
        int n = sizeof(arr) / sizeof(int);
        sort(arr, arr + n);
        int count = 0;
        int unique = -1;
        for (int i = 0; unique == -1 && i < n - 1; ++i) {
            if (arr[i] != arr[i + 1]) {
                if (count==0)
                    unique = arr[i];
                else
                    count = 0;
            }
            else {
                count++;
            }
        }
        if (count == 0 && unique ==-1)
            unique = arr[n-1];
        cout << unique;
        return 0;
    }
    

    【讨论】:

      【解决方案3】:

      我提出以下代码:

      #include <iostream>
      #include <algorithm>
      
      using namespace std;
      
      int main()
      {
      int arr[5] = { 1,2,3,2,1 };
      
      int N = sizeof(arr) / sizeof(arr[0]);
      sort(arr, arr + N);
      int index = -1;
      
      // Check first element is different comparing with second one. 
      // If the array is only one element, then first element is unique
      if (N == 1 || arr[0] != arr[1]) {
          index = 0;
      }
      else {
          int i = 1;
          while (i < N - 1 && index == -1) {
              // Check number is different to previous and different to next value
              if (arr[i - 1] != arr[i] && arr[i] != arr[i + 1]) {
                  index = i;
              }
              else
              {
                  i++;
              }
          }
          if (index == -1) {
              // No found, check last element comparing with previous
              if (arr[i - 1] != arr[i]) {
                  index = i;
              }
          }
      }
      
      if (index != -1) {
          // Have found min value
          cout << "Min not repeated value is " << arr[index] << endl;
      }
      else {
          // All elements are repeated
          cout << "No min value" << endl;
      }
      }
      

      数组排序后,我将每个值与前一个值和下一个值进行比较,以检查它是否唯一。但是对于第一个和最后一个元素是一种特殊情况。

      【讨论】:

        【解决方案4】:

        使用我在 cmets 中所说的,加上一个额外的布尔值。

        int arr[] = { 1, 2, 1, 3, 4, 1, 2 };
        int n = sizeof( arr ) / sizeof( int );
        
        std::sort( arr, arr + n );
        
        bool match = false;
        for ( int i = 0; i < n; ++i ) {
            if ( i == n - 1 || arr[i] != arr[i + 1] ) {
                if ( match )
                    match = false;
                else
                    return arr[i];
            } else {
                match = true;
            }
        }
        
        return -1; // made up number in case all duplicates
        

        如果两个值相等,那么我们就知道不能再使用那个值,所以我将match 设置为true。如果它们不相等,那么如果它已经被取消资格,我忽略它并将match设置回false,否则,返回该值。

        有更优雅的方法可以做到这一点;这只是最简单的。

        【讨论】:

        • 修复了它,现在它会:)
        猜你喜欢
        • 2020-09-22
        • 2020-02-02
        • 2021-06-15
        • 1970-01-01
        • 1970-01-01
        • 2020-04-20
        • 2020-02-22
        • 2019-09-11
        • 1970-01-01
        相关资源
        最近更新 更多