Java 在O(N)时间内对数组排序
给定整数Java 在O(N)时间内对数组排序,java,arrays,algorithm,sorting,Java,Arrays,Algorithm,Sorting,给定整数1,2,3,…,N和字符“(空格)的数组A 我们希望将其排序为[1,2,3,…,N,“],其中我们只能将整数与“”交换,但不能相互交换,因此允许交换(3,”,而不允许交换(1,2) 我的尝试是将空间表示为“-1”,并在O(N)时间内搜索它,然后再次从i=1到N+1,如果我看到例如A[2]=7,我将A[7]与“交换,然后我将A[2]与交换同时跟踪“的位置,因为这是交换的唯一方式,因此7将以A[7]结束(索引移动除外) 我编写的代码如下: public static int[] arrayS
1,2,3,…,N
和字符“
(空格)的数组A
我们希望将其排序为[1,2,3,…,N,“]
,其中我们只能将整数与“”交换,但不能相互交换,因此允许交换(3,”
,而不允许交换(1,2)
我的尝试是将空间表示为“-1”
,并在O(N)时间内搜索它,然后再次从i=1
到N+1
,如果我看到例如A[2]=7
,我将A[7]
与“
交换,然后我将A[2]
与交换
同时跟踪“
的位置,因为这是交换的唯一方式,因此7
将以A[7]
结束(索引移动除外)
我编写的代码如下:
public static int[] arraySort(int[] array){
int space = 0;
for(int i = 0; i<array.length; i++ ){
if(array[i] == -1){
space = i;
}
}
for(int i = 0; i<array.length; i++){
if(array[i] != i+1 && array[i] !=-1){
swap(array, array[i]-1 , space);
space = array[i]-1;
swap(array, i, space);
space = i;
}
}
return array;
}
public static void swap(int[] arr, int ind1, int ind2){
int temp = arr[ind2];
arr[ind2] = arr[ind1];
arr[ind1] = temp;
}
公共静态int[]数组排序(int[]数组){
int空间=0;
对于(int i=0;i使用计数排序技术。始终将空格放在数组的末尾。您有一个大小为N+1的数组。现在,尝试从第一位读取数组。例如,它是3。您应该将3放在数组的第三位。为此,请将数组的当前第三位值与空格交换,然后交换t的第一位他用第三个数组交换第一个数组,然后用数组的最后一个项目交换第一个数组。后一个步骤将用于保持数组末尾的空间
public static int[] arraySort(int[] array){
int N = array.length - 1;
for(int i = 0; i < N; i++){
int currentNum = array[i]-1;
swap(array, currentNum, N); // swap currentNum-th item with space as the last memebr of the array
swap(array, i, currentNum); // swap the current item with its place
swap(array, i, N); // swap the space with the last item.
}
return array;
}
public static void swap(int[] arr, int ind1, int ind2){
int temp = arr[ind2];
arr[ind2] = arr[ind1];
arr[ind1] = temp;
}
公共静态int[]数组排序(int[]数组){
int N=array.length-1;
对于(int i=0;i
在上面的代码中,我们假设起始数组中的空格位置在最后一个。如果不是,您可以在O(N)
中找到它,并将其与数组的最后一个位置交换。步骤1创建一个查找数组
public static int[] arraySort(int[] array){
int N = array.length - 1;
for(int i = 0; i < N; i++){
int currentNum = array[i]-1;
swap(array, currentNum, N); // swap currentNum-th item with space as the last memebr of the array
swap(array, i, currentNum); // swap the current item with its place
swap(array, i, N); // swap the space with the last item.
}
return array;
}
public static void swap(int[] arr, int ind1, int ind2){
int temp = arr[ind2];
arr[ind2] = arr[ind1];
arr[ind1] = temp;
}
将数组设为N+1长,其中查找数组中的每个值都表示它在要排序的数组中的位置。可以将查找[0]设为空间所在的位置。创建这样的数组需要O(N)个时间。
在[7,3,5,4,6,1,2,-1]的情况下,你做一个数组[7,5,6,1,3,2,4,0]
步骤2:将空间移动到阵列的起始位置
您可以通过查找[0]找到空间的当前索引,如果它已经位于索引0,则转到下一步,否则使用索引0进行交换。然后您应该更新循环数组以反映更改。即查找[0处的值]=[空间开始的位置]
步骤3:将空间与数组中的下一个元素交换
现在用1
交换空间。你可以用查找数组找到它
第4步重复
如果需要,现在将空间移动到索引1,并使用2
交换。然后将空间移动到索引2,并使用3
交换。重复此操作,直到排序完成
创建查找数组的总时间为N,每个元素交换2次,总时间为O(3N)。您描述的算法非常正确,但您犯了几个错误
首先,您可能需要在同一位置交换多次。其次,如果您击中空格,则必须将其放置在正确的位置。这是您的循环已修复。请注意,我提前一个位置停止了迭代
for(int i = 0; i<array.length-1; i++){
while (array[i] != i+1){
if (space==i) {
// it's the space
swap(array, i, array.length-1);
space = array.length-1;
} else {
swap(array, array[i]-1, space);
space = array[i]-1;
swap(array, space, i);
space = i;
}
}
}
尽管我们添加了一个内循环,但理解为什么仍然是O(n)是很重要的:内循环的每次迭代都会精确地确定一个数字的位置,之后我们将不再移动该数字。这最多可能发生n次,因为只有那么多的数字需要修正。“给定整数1,2,3,…,N的数组A”
,听起来数组不能包含负整数,但在测试用例中([7,3,5,4,6,1,2,-1]
),您使用的是负整数。输入数组可以包含负整数和正整数,还是仅包含正整数?-1表示空格字符,它不是数组中的整数,数组大小为N+1,仅包含1,2,3,…,N,-1(空格)如何,我不允许创建另一个数组,仅使用“”。我认为它必须放在适当的位置,加上计数排序中的一些步骤在这里是多余的,比如计算范围内每个数字的多重性,因为它显然是1。当你使用N
作为空间时,为什么还要声明一个space
变量?@Holger不幸的是,我听不懂你说的。你说swap(array,currentNum,N);
现在,空格位于位置currentNum
。那么,为什么我们不能交换(array,i,currentNum);
?这取决于“space”的含义。通常,“space”是一个位置,而不是一个数值。你似乎认为空间是你移动到位置的值<代码> CurrutnUn/Case>,但是与你自己的评论相矛盾,然后用注释“<代码>交换当前项目与其位置< /代码>”。。无论如何,您的代码的实际问题已经由描述过了。您声明一个根本不用的变量space
。@Holger感谢您提供了额外的space
variable。无论如何,将当前项与其位置互换是通过提供的示例解释的。我的意思是互换<代码> 3 第三位是当前的空间。我宁愿使用<代码>交换(数组、当前对象、数组、长度-1);交换(数组、i、数组、长度-1);交换(数组、当前对象、数组、长度-1);< /COD>考虑“空间”为位置(<代码>数组>长度-1 < /代码>)它当前包含的不是值。但是…这仍然是O(n)
?@Holger您的第二次交换会破坏OP的ru吗