【问题标题】:How to find missing number in array如何在数组中找到缺失的数字
【发布时间】:2021-12-24 19:23:50
【问题描述】:
#include <iostream>
#include <algorithm>
using std::cin;
using std::cout;
using std::endl;
using std::sort;
int main()
{
    int x = 0;
    int n;                                  // Enter Size of 2 array
    cin >> n;                               // enter 5
    long long *ptr1 = new long long[n - 1]; // size of array must be less than 5 by one n-1
    for (int x = 0; x < n - 1; x++)
    {
        cin >> ptr1[x];
    }
    sort(ptr1, ptr1 + (n - 1));
    for (int z = 1; z < n; z++)
    {
        if (z != ptr1[x])
        {
            cout << z;
            break;
        }
        x++;
    }
    return 0;
}

你得到了 1,2,…,n 中的所有正整数,除了一个整数。找出缺失的整数。

输入 输入的第一行包含一个整数n(2≤n≤2×105)。

输入的第二行包含从 1 到 n(含)的 n−1 个不同整数。

输出 打印缺失的整数。 当我尝试汇总此代码时,我在测试 10 中出错了,但我不知道为什么!而且他没有显示测试,所以出了什么问题?

【问题讨论】:

  • 你不需要存储所有的数字,或者排序任何东西,或者搜索任何东西。考虑从 1 到 n 的数字之和,并与输入中的数字之和进行比较。
  • 你提到“测试10”,这个测试是什么?该特定测试的输入是什么?您是否尝试过使用调试器单步执行代码以查看该输入会发生什么?
  • 您可以考虑this Q&A 以获得更好的算法方法(正如@molbdnilo 指出的那样)。
  • 第二个循环不需要重新初始化 x
  • 旁注(请参阅@molbdnilo):从 1 到 n 的数字总和可以计算为 n * (n+1) / 2 - 仅适用于您可能还不知道的情况...

标签: c++ arrays


【解决方案1】:

如果从所有数字 1、2、...、n 的预期总和中减去输入的数字,则可以更直接地解决这个问题(参见@molbdnilo、@Aconcagua 和 @marcus-müller 的 cmets ):

#include <iostream>

int main() {
    std::size_t n;
    std::cin >> n;
    
    std::size_t sum{ n*(n + 1)/2 };
    for (std::size_t idx = 1; idx != n; ++idx) {
        std::size_t thisNumber;
        std::cin >> thisNumber;
        sum -= thisNumber;
    }
    
    std::cout << "Missing number: " << sum << std::endl;
}

【讨论】:

  • 如果我们的目标是最短的解决方案:首先计算预期的总和,然后在您的 for-loop 中,简单地从该总和中连续减去。最后,sum 变量中剩下的就是缺失的数字。
  • 谢谢——但我只添加了总和,@molbdnilo 暗示了算法本身,实际上值得称赞......
【解决方案2】:

我有三个答案:

  1. 此程序泄漏内存
  2. 你包含&lt;algorithm&gt;请使用它。 (关注cppreference
  3. 剧透vectoriotamismatch

另外,您不要在第二个循环之前重置 x。 除非丢失的整数是数组的最后一个,并且不等于1

,否则这永远不会起作用
  // for (... z)
    if (z != ptr1[x] /* Here */) {
      // print 1, end loop OR invoke undefined behavior
    }
    x++; // Now x is equal to (n - 1)

【讨论】:

    【解决方案3】:

    您的代码存在一些问题:

    long long *ptr1 = new long long[n - 1]; 
    

    你打电话给new,没有delete。这会造成内存泄漏。

    您尚未重新初始化 x,因此对 ptr1[x] 的任何访问都超出了范围。

    尽情享受所有这些,您的代码将如下所示:

    #include <iostream>
    #include <algorithm>
    #include <vector>
    int main()
    {
        int n;                                  
        cin >> n;                               
        std::vector<int> vec(n-1); // std::vector instead
        for (int x = 0; x < n - 1; x++)
        {
            std::cin >> vec[x];
        }
        std::sort(vec.begin(), vec.end());
        int x = 0; // use another variable instead of reused the old one.
        for (int z = 1; z < n; z++)
        {
            if (z != vec[x])
            {
                std::cout << z;
                break;
            }
            x++;
        }
        return 0;
    }
    

    但是,这无论如何都不是最好的方法。正如@molbdnilo 建议的那样:

    #include <iostream>
    
    int main()
    {
        int n;
        std::cin >> n;
    
        int sum{};
        for (int i = 0; i < n - 1; ++i)
        {
            int tmp;
            std::cin >> tmp;
            sum += tmp;
        }
        std::cout << (n + 1) * n / 2 - sum;
    }
    
    

    【讨论】:

      【解决方案4】:

      积木:

      • 预期总和:int expected_sum = n * (n + 1) / 2;
      • 在阅读n 后提供给测试的所有整数的总和:
        #include <iterator> // istream_iterator
        #include <numeric>  // accumulate
        int sum = std::accumulate(std::istream_iterator<int>(std::cin),
                                  std::istream_iterator<int>{}, 0);
        
      • 现在,expected_sum - sum 应该会为您提供缺失值。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-12-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-12-03
        • 2011-11-11
        • 2017-11-07
        相关资源
        最近更新 更多