Java 重新排列数组,使‘;arr[j]’;成为‘;i’;如果‘;arr[i]’;is‘;j’;带模

Java 重新排列数组,使‘;arr[j]’;成为‘;i’;如果‘;arr[i]’;is‘;j’;带模,java,arrays,algorithm,modulo,Java,Arrays,Algorithm,Modulo,我试图解决Geeksforgek的下一个问题。 给定一个大小为n的数组,其中所有元素都在0到n-1之间,请更改arr[]的内容,以便将arr[i]=j更改为arr[j]=i。 我看到了一个使用模的解决方案: 在一次扫描中 arr[arr[i]%n]+=n*i 在下一次扫描中 arr[i]/=n 他的解释是: 我在这里做的是这样的,我知道每个位置都有一个小于n的元素,因为它必须表示数组的索引,对于任何数字x,x小于n,x%n=x基本上当我写的时候,arr[arr[i]%n]如果arr[i]=j 我

我试图解决Geeksforgek的下一个问题。 给定一个大小为n的数组,其中所有元素都在0到n-1之间,请更改arr[]的内容,以便将arr[i]=j更改为arr[j]=i。 我看到了一个使用模的解决方案:

在一次扫描中 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..n-1范围内的数字。假设如果要存储x和y,则实际将元素设置为z=n*x+y。您可以通过执行z/n来检索x,通过执行z%n来检索y


现在,解决方案使用上述技巧将新数字放入数组(在x槽中),而不会干扰旧数字(仍在y槽中)。在第二遍中,旧的数字被删除。

我实际上根本没有得到相同的答案。arr=[1 4 5 0 2 3];n=6;i=4;arr[arr[4]%6]+=6*4;arr[2]+=24;arr[2]=29;arr[4]=2/6;arr[4]=0@InfinityCounter您应该在arr[2]上继续。我不明白为什么没有人能给我答案。我试着编辑我的问题,也许现在它更清楚了。