我试图从geeksforgeek website解决下一个问题。 给定大小为n的数组,其中所有元素的范围从0到n-1,更改arr []的内容,以便arr [i] = j更改为arr [j] = i。 我看到了使用modulo的解决方案:
在一次扫描中 arr [arr [i]%n] + = n * i 并在下一次扫描中 ARR [I] / = N
他的解释:
我在这里做的是这个,我知道每个位置都有一个小于n的元素,因为它必须代表数组的索引,对于任何数字x,这样x小于n,x%n = x基本上是我写的时候,arr [arr [i]%n]和arr [i] = j 我正在访问arr [j]的元素 现在你会注意到,我用n * i递增每个这样的元素 在这一步,我将两个元素存储在一个位置, 例如:假设arr [2] = 5且arr [5] = 4且总共有6个元素 我会做arr [arr [2]%6] = arr [5%6] = arr [5] = 4 + 12即4 + 2 * 6 现在这等于16,这包含两个数字,如果我不是原始数字,即在我改变所有值的第一次扫描期间,我写arr [5]%6 =(4 + 2 * 6 )%6 = 4%6 + 2 * 6%6 = 4 + 0 = 4并且在第二次扫描期间,当我想将数组更新为最终结果时arr [5] / 6 =(4 + 2 * 6) / 6 = 4/6 + 2 * 6/6 = 0 + 2 = 2我希望这个解释可以帮到你,一切顺利
但我无法理解它背后的逻辑/数学。有人能用数学方法解释方法的逻辑吗?
答案 0 :(得分:0)
这里的技巧是在一个数组元素中存储0..n-1范围内的两个数字。假如你想存储x和y,你实际上将元素设置为z = n * x + y。您可以通过执行z%n来执行z / n和y来检索x。
解决方案现在使用上述技巧将新数字放入数组(在x插槽中)而不会打扰旧数字(仍在y槽中)。在第二遍中,旧的数字被删除。