制定解决问题的方法?

时间:2015-03-20 10:58:55

标签: c++ algorithm

给出了由N个不同整数组成的零索引数组A.该数组包含[1..(N + 1)]范围内的整数,这意味着只缺少一个元素。

您的目标是找到缺少的元素。

写一个函数:

int solution(int A[], int N); 

给定零索引数组A,返回缺少元素的值。

例如,给定数组A使得:

A[0] = 2 A[1] = 3 A[2] = 1 A[3] = 5

该函数应该返回4,因为它是缺少的元素。

假设:

N is an integer within the range [0..100,000];
the elements of A are all distinct;
each element of array A is an integer within the range [1..(N + 1)].

复杂度:

expected worst-case time complexity is O(N);
expected worst-case space complexity is O(1), beyond input storage (not counting the storage required for input arguments).

对于有两个元素

的情况不起作用
int solution(vector<int> &A) {

    sort(A.begin(), A.end());
    int missingIndex = 0;

    for (int i = 0; i < A.size(); i++)
    {
        if ( i != A[i]-1)
        {
            missingIndex = i+1;
        }

    }
    return missingIndex;
}

6 个答案:

答案 0 :(得分:5)

由于您的数组是零索引且数字从1到N + 1,因此该语句应为:

if ( i != A[i]-1)

此外,您应该在更新missingIndex后立即从for循环中断开,因为缺少元素之外的所有条目都应具有(i!= A [i] -1)

此外,由于您的解决方案的排序是O(NlogN)而不是O(N)。

相反,您可以对数组(using unsigned long long int)中的所有元素求和,并检查其与N(N+1)/2的差异

答案 1 :(得分:1)

您可以使用arithmetic progression的简单数学公式来获取从1到N + 1的所有数字的总和。然后迭代所有给定的数字并计算该总和。缺少的元素将是两个总和之间的差异。

int solution(std::vector<int> &a) {
    uint64_t sum = (a.size() +1 ) * (a.size() + 2) / 2;
    uint64_t actual = 0;
    for(int element : a) {
        actual += element;
    }
    return static_cast<int>(sum - actual);
}

答案 2 :(得分:1)

使用STL的所有力量:

#include <algorithm>
#include <functional>

int solution(vector<int> &A) {
    return std::accumulate(A.begin(), A.end(), (A.size()+1) * (A.size()+2) / 2, std::minus<int>());
}

答案 3 :(得分:0)

此解决方案使用值的符号作为标志。最坏的情况是需要两次通过元素。 N(N + 1)/ 2解决方案只需要一次通过。

int solution(vector<int> &a) {
    int n = (int)a.size();
    for(auto k : a)
    {
        int i = abs(k) - 1;
        if (i != n)
            a[i] = -a[i];
    }

    for (int i = 0; i < n; ++i)
        if (a[i]>0)
            return i+1;
    return n+1;
}

答案 4 :(得分:0)

我用这种方式解决了这个问题并考虑将其发布在这里供我自己参考以供将来和其他人使用:)

#include <cstdint>
#include <numeric>
int solution(vector<int> &A) {
   uint64_t sumAll = (A.size() + 1) * (A.size() + 2) / 2;
   uint64_t sumA = std::accumulate(A.begin(), A.end(), 0);
   return sumAll- sumA;
}

答案 5 :(得分:0)

我用此解决方案解决了它,也许有更好的选择,但是我用不同的值对其进行了测试,发现它可以正常工作,而其他解决方案却给了我奇怪的结果。 例如:

std::vector<int> A = { 12,13,11,14,16 };
std::vector<int> A2 = { 112,113,111,114,116 };


int  Solution(std::vector<int> &A)
{
int temp;
for (int i = 0; i < A.size(); ++i)
{
    for (int j = i+1;j< A.size();++j )  
{
    if (A[i] > A[j])
        {
            temp = A[i];
            A[i] = A[j];
            A[j] = temp;
        }
    }
}

for (int i = 0; i < A.size()-1;++i)
{
    if ((A[i] + 1 != A[i + 1]))
    {
    return (A[i] + 1);
    }
    if(i+1 == A.size() - 1)
    return (A[i+1] + 1);

}}

现在一切都很好,但是如果我将下面的方法与上面的数组一起使用,除小数<10;之外我将得到错误的值。

 std::vector<int> A = { 12,13,11,14,16 };
 int Solution_2(std::vector<int> &A) 
{
unsigned int n = A.size() + 1;
long long int estimated = n * (n + 1) / 2;
long long int total = 0;
for (unsigned int i = 0; i < n - 1; i++) total += A[i];
return estimated - total;
}

我将得到-45的结果。

或者如果我使用数组A,则此结果也相同:

std::vector<int> A = { 12,13,11,14,16 };
int Solution_3(std::vector<int> &A) 
{
 uint64_t sumAll = (A.size() + 1) * (A.size() + 2) / 2;
 uint64_t sumA = std::accumulate(A.begin(), A.end(), 0);
 return sumAll - sumA;
}

希望有人解释为什么会发生这种情况。