【问题标题】:Given an array,find the number of element it can divide or divided by the remaining elements of the array给定一个数组,找出它可以除或除以数组的其余元素的元素个数
【发布时间】:2021-10-05 16:27:59
【问题描述】:
Input Array: int A={2,3,4,5,6} , array is not always sorted.

output Array:{2,1,1,0,2}
  • 因为我们可以看到A[0] 可以除以 4 和 6,所以它有输出 2。
  • A[1]只能除6,输出1。
  • A[2] 除以 2,所以有输出 1。
  • A[3]不能除或被除所以有输出0。
  • A[4] 除以 2 和 3,所以输出为 2。

我能够使用时间复杂度为 o(n*n) 的蛮力方法来解决它。什么是解决它的最有效方法。谢谢。 我的代码:

    #include<iostream>
    #include<vector>
    using namespace std;
    //Function to return output vector
    vector<int>solve(vector<int> &A) {
        vector<int>v;
        for(int i=0;i<A.size();i++){
            int count=0;
            for(int j=0;j<A.size();j++){
                if(i!=j){
                    if(A[j]%A[i]==0 || A[i]%A[j]==0){
                        count++;
                    }
                }
            }
            v.push_back(count);
        }
        return v;
    }
    
    int main(){
        vector<int>v={2,3,4,5,6};
        vector<int>s;
        s=solve(v);
    //printing the output array
        for(int i=0;i<s.size();i++){
            cout<<s[i]<<" ";
        }
    }

【问题讨论】:

  • 不,它没有排序,第二个示例测试用例是无序的。
  • 某种记忆或动态编程?由于您已经用A[0] 划分了所有其余数字,因此您不必再这样做了。
  • 每个元素的选择范围是多少?

标签: c++ algorithm vector data-structures dynamic-programming


【解决方案1】:

简单的修改有助于减少一半的迭代,但复杂性仍然是二次方的。

似乎没有办法更快地解决这个问题(使用分解等)

 make v: vector of A.size zeros
 ...
      for(int j=i+1;j<A.size();j++){
         if(A[j]%A[i]==0 || A[i]%A[j]==0){
             increment v[i] and v[j]

【讨论】:

  • 非常感谢您,先生,赞成您的友好回答,这是在我的在线编码回合中被问到的,我希望它会起作用,但不确定它会通过他们所有的测试用例。
【解决方案2】:

对于is divided by,引用每个元素的计数;找到每个元素的除数并添加任何匹配的计数。

对于divides,引用每个可见除数的计数;添加元素的任何匹配项的计数。

O(n * sqrt m) 其中 m 是最大值(输入)。

【讨论】:

    【解决方案3】:

    我不确定你的问题是否可能,但是像这样的事情怎么样

    namespace {
        std::unordered_map<int, std::vector<size_t>> const factors{
            {1, {1}},
            {2, {1}},
            {3, {1}},
            {4, {1, 2}},
            {5, {1}},
            {6, {1, 2, 3}},
        };
    }
    
    std::vector<int>solve(std::vector<int> &A) {
        std::unordered_map<int, std::vector<size_t>> indexedFactors;
        size_t idx = 0;
        for(auto num: A) {
            // Lookup the factors of num from the table
           for(auto factor: factors.at(num)) {
               //  and add them to the map with indexes pointing to the number that has them as a factor
               indexedFactors[factor].push_back(idx);
           }
           ++idx;
        }
        std::vector<int> res(A.size());
        idx = 0;
        for(auto num: A) {
            if (indexedFactors.find(num) != indexedFactors.end()) {
                for(auto i: indexedFactors.at(num)) {
                    res[i]++; // Track the divides
                    res[idx]++; // Track the divided by
                }
            }
            ++idx;
        }
        return res;
    }
    

    您可以有一个预先计算的数字表及其因数(代码中的factors)。不要将数字本身作为自身因素添加到列表中。

    然后您可以遍历输入数组并将每个数字的因子添加到映射中,并继续添加它们是因子的数字的索引。例如如果num 为 6,则将 1、2 和 3 添加到输入数组中索引为 6 的映射中。对所有数字执行此操作。

    现在,遍历输入数组,然后为每个数字检查它是否在 indexedFactors 映射中,并在所有这些索引处增加结果数组中的计数。这会处理 divides 部分。此外,增加这些时间的计数以处理 除以 部分。例如如果num 为 2,则输入数组中的索引为 4 和 6,这些索引将在结果数组中更新。但是由于 2 除以 4,所以 4 也可以被 2 整除,因此结果数组中索引为 2 处的计数会增加。

    复杂度为O(n * m),其中m 是输入数组中每个数字的因子数(~√num)。

    【讨论】:

    • 非常感谢您的详细回答,我希望它会奏效。但是找到所有数字的因子并将它们存储在地图中需要额外的时间和空间复杂性。
    • @def__init__ 数字的范围是多少?您可以预先计算它们并节省生成它们的时间。另外输入中可以有多少个数字?但确实,空间复杂度很高。
    猜你喜欢
    • 2020-04-24
    • 1970-01-01
    • 2012-03-18
    • 2017-09-12
    • 1970-01-01
    • 1970-01-01
    • 2012-03-18
    • 2015-08-15
    相关资源
    最近更新 更多