距离可被整数整除的点对

Posted

技术标签:

【中文标题】距离可被整数整除的点对【英文标题】:Pair of points with distance divisible by integer 【发布时间】:2015-06-14 10:02:34 【问题描述】:

我遇到了一个面试问题,尽管我一直在尝试自己解决这个问题,但我认为我需要一些帮助。

我有一个整数数组(正数和负数)代表空间中的点,两点之间的距离定义为 abs(A[i]-A[j]) 我需要检查那个距离能被给定整数 M 整除。

所以情况就是这样:

数组:[-3 -2 1 0 8 7 1]

M = 3

abs(A[1]-A[2]) = 3(例如它可以被整数整除)

复杂度应该是O(N+M),空间是O(M)

现在是这些问题

1)我知道有一种方法可以在不使用带有两个“for 循环”的明显解决方案的情况下考虑所有夫妻,因为复杂性将是 N^2,这是不可取的,但我不知道如何去做吧

2)复杂度 O(N+M) 意味着我需要使用两个 for 循环,但不能在另一个循环中使用一个?(我的意思是两个单独的 for 循环),我想在这里理解的是,如果给出的复杂性可以指导我朝着我应该使用的最佳算法前进。

3)当规范说整数名称为M,复杂度为O(N+M)时,这是否意味着整数M和复杂度有关系,或者只是名称为一样吗?

4)怎么做?

我希望我已经足够清楚了,如果没有,请告诉我,我会尝试更好地解释自己。

好的,让我们看看我是否理解正确,这是我目前正在尝试的:

int testCollection[7];

testCollection[0] = -3;
testCollection[1] = -2;
testCollection[2] = 1;
testCollection[3] = 0;
testCollection[4] = 8;
testCollection[5] = 7;
testCollection[6] = 1;

int arrayCollection[7];

for (unsigned int i = 0; i < 7; i++)

    arrayCollection[i] = 1000;


for (unsigned int i = 0; i < 7; i++)


    arrayCollection[i] = testCollection[i]%3;

 

arrayCollection 现在包含:[0, -2, 1, 0, 2, 1 ,1 ]

我第二次不明白你的意思,你能更具体一点吗?想象一下我是个孩子:)

干杯

附言我不想过多打扰您,所以如果您愿意,可以向我指出一些我可以阅读的有关该主题的文档,不幸的是,谷歌搜索我没有找到太多。

【问题讨论】:

关于3)当整数-是-M时,复杂度应该是O(N+M)。即,当 M 较大时,您比 M 较小时获得更多时间。 【参考方案1】:

两个点具有相同的mod M 当且仅当它们是M 的整数倍。因此,创建一个大小为mod M 的整数数组A,并循环遍历N 整数,对于每个这样的整数N[i],影响A[N[i] % M]++

最后,如果任何条目是&gt;1,那么至少有一对整数是M 的倍数。

要实际提取解决方案(即,获取与k*M 不同的值,而不是简单地知道有一些值),您可以将整个A 初始化为MAXINT,并将值分配给A第一次看到特定的mod M。第二次你有一对有效的值。

【讨论】:

【参考方案2】:

您能否为您提供的解决方案分享一些代码。 或者用这条线来澄清你的意思 对于每个这样的整数 N[i],影响 A[N[i] % M]++。

For ex - int[] nArr = new int[] -3,-2, 1, 0,8,7,1 ; 然后它抛出 ArrayIndexOutOfBoundException 因为有些数字是负数

【讨论】:

【参考方案3】:

这行得通。它在 O(M+N) 和 O(M) 额外空间中运行。

    modulus = (num,n)=>
    if(num<0)
        do
            num += n;
        while(num<0);
    
    return num%n;

var arr=[-5,-2,4,7,10,0,8],m=3,mod=[];
for(var index=0;index<m;index++)
    mod[index]=0;

for(index=0;index<arr.length;index++)
    mod[modulus(arr[index],m)]++;

mod.sort(function(a,b)
    return a-b;
);
if(mod[m-1] > 1)
    console.log(mod[m-1]);

我最近在一次采访中遇到了这个问题。所以,我认为你的问题是我被问到的同一个问题的一部分。

【讨论】:

【参考方案4】:

在 kotlin 中实现,请查看以下内容:

fun largestSubSetDivisible(array: Array<Int>, m: Int):Int 
    val result = Array(1)  1 
    largestSubSetDivisible(array, m = m, result = result)
    return result[0]


fun largestSubSetDivisible(
    array: Array<Int>,
    arr: IntArray = IntArray(array.size)  0 ,
    i: Int = 0,
    m: Int,
    result: Array<Int> = Array(1)  1 
) 
    fun checkDivisionPair(array: List<Int>, m: Int): Boolean 
        for (j in 0 until array.size - 1) 
            if ((array[j] - array[j + 1]) % m != 0)
                return false
        
        return true
    
    if (i == array.size) 
        val count = arr.count  it == 1 
        if (result[0] < count) 
            val ar = array.filterIndexed  index, _ -> arr[index] == 1 
            if (checkDivisionPair(ar, m))
                result[0] = count
        
        return
    
    arr[i] = 0
    largestSubSetDivisible(array, arr, i + 1, m, result)
    arr[i] = 1
    largestSubSetDivisible(array, arr, i + 1, m, result)

【讨论】:

【参考方案5】:

基于C++的解决方案

int sol(std::vector<int> vec, int M)

    std::vector<int> mod(M);
    for (int p = 0; p < M; ++p) 
        mod[p] = 0;
    
    for(int i : vec)
    
        mod[(std::abs(vec[i]) % M)] = mod[(std::abs(vec[i]) % M)] + 1;
    
    std::sort(mod.begin(), mod.end());
    return mod[M - 1];

int main( void )

    std::cout << sol( -3, -2, 1, 0, 8, 7, 1 , 3) << std::endl; // 4
    std::cout << sol(7, 1, 11, 8, 4, 10, 8) << std::endl; // 2
    return 0;

【讨论】:

以上是关于距离可被整数整除的点对的主要内容,如果未能解决你的问题,请参考以下文章

1015. 可被 K 整除的最小整数

查找可被 6 或 7 整除但不能同时被 6 或 7 整除的整数

python 使用替代总和检查整数可被3整除

python 使用除法运算,检查整数可被3整除

python 使用十六进制检查整数可被3整除

python 使用字符串转换检查整数可被3整除