我看到一个面试问题要求
Interchange arr[i] and i for i=[0,n-1]
示例:
输入:1 2 4 5 3 0
回答:5 0 1 4 2 3
解释:a[1]=2 in input , so a[2]=1 in answer so on
我尝试了这个但没有得到正确答案。
我能做的是:for a pair of numbers p and q , a[p]=q and a[q]=p .
任何想法如何改进它是受欢迎的。
FOR(j,0,n-1)
{
i=j;
do{
temp=a[i];
next=a[temp];
a[temp]=i;
i=next;
}while(i>j);
}
print_array(a,i,n);
如果它包含一个带有一些解释的伪代码,我会更容易理解你的答案。
编辑:我说它是循环排列所以更改了问题标题。
答案 0 :(得分:3)
以下是我提出的(Java代码)。
对于x
中的每个值a
,它会将a[x]
设置为x
,并将x
设置为已覆盖的值(用于a[a[x]]
1}}),并重复直到它回到原始x
。
我使用负值作为标志来表示该值已经处理过。
运行时间:
由于它只处理每个值一次,因此运行时间为O(n)
。
<强>代码:强>
int[] a = {1,2,4,5,3,0};
for (int i = 0; i < a.length; i++)
{
if (a[i] < 0)
continue;
int j = a[i];
int last = i;
do
{
int temp = a[j];
a[j] = -last-1;
last = j;
j = temp;
}
while (i != j);
a[j] = -last-1;
}
for (int i = 0; i < a.length; i++)
a[i] = -a[i]-1;
System.out.println(Arrays.toString(a));
答案 1 :(得分:1)
以下是我的建议,O(n)
时间,O(1)
空间:
void OrderArray(int[] A)
{
int X = A.Max() + 1;
for (int i = 0; i < A.Length; i++)
A[i] *= X;
for (int i = 0; i < A.Length; i++)
A[A[i] / X] += i;
for (int i = 0; i < A.Length; i++)
A[i] = A[i] % X;
}
一个简短的解释:
我们使用X
作为原始数组中值的基本单位(我们将原始数组中的每个值乘以X
,这大于A
中的任何数字 - 基本上A
+ 1的长度。所以在任何时候我们都可以通过A[i] / X
来检索原始数组的某个单元格中的数字,只要我们没有向该单元格添加超过X
。
这让我们有两层值,其中A[i] % X
表示排序后单元格的值。这两个层不会在整个过程中相交。
完成后,我们会通过执行A
从原始值乘以X
来清除A[i] = A[i] % X
。
希望足够干净。
答案 2 :(得分:0)
也许可以通过使用输入排列的图像作为索引:
void inverse( unsigned int* input, unsigned int* output, unsigned int n )
{
for ( unsigned int i = 0; i < n; i++ )
output[ input[ i ] ] = i;
}