我正试图像这样打开一个数组:
0, 1, 2, 2, 1, 0, 1, 0, 0, 1, 2
进入这个:
0 0 0 0 1 1 1 1 2 2 2
这是我的代码:
public static int[] sortDNF(int[] tape) {
int smaller = 0; // everything with index < smaller is 0
int bigger = tape.length - 1; // everything with index > bigger is 2
int current = 0; // where we are looking now
int tmp;
while (current <= bigger) {
if (tape[current] == 0) {
tmp = tape[smaller];
tape[smaller] = tape[current];
tape[current] = tmp;
smaller++;
}
if (tape[current] == 2) {
tmp = tape[bigger];
tape[bigger] = tape[current];
tape[current] = tmp;
bigger--;
}
current++;
}
return tape;
}
这就是它产生的:
0 0 0 1 1 1 1 0 2 2 2
我的问题是什么?
答案 0 :(得分:4)
每次循环都不应该增加电流,因为它应该代表1和未知数之间的分区。例如,当您点击前2时,您最终将其与另外2个交换,然后继续前进。事实上,2后来换成0是偶然的。较小和当前之间的元素应始终为1,并且会被打破。
current ++只能在磁带[current]中完成!= 2个案例。当磁带[current] = 0时可以这样做,因为你没有改变[较小 - &gt; current] = 1-only条件。当磁带[current] = 1时移动它是可以的,因为它满足了1-only条件。
......但我还没试过。
答案 1 :(得分:2)
对于那些没有研究过这个问题的人来说,排序就足以提供一个解决方案,但它已经(或可能)不必要了。解决DNF问题只需要将所有类似项目一起移动,但您不必按任何特定顺序放置不相等的项目。
使用预期的O(N)复杂度来解决DNF非常容易,其中(大多数正常形式的)排序具有O(N lg N)复杂度。不是重新排列输入元素,而是简单地计算具有任何给定值的元素,然后打印出正确数量的元素,这样更容易。由于不相等元素的顺序无关紧要,因此通常将计数存储在哈希表中。
答案 2 :(得分:1)
问题是您在链中稍后回复(可能不存在)值以交换错误跳过的1个值,尝试您的算法:
1 2 0
2在正确的位置交换,但当前指数已经超过指数0的最终结果,导致:
1 0 2
因此,在检查该索引处的新值之前,请不要增加当前值。
答案 3 :(得分:1)
public static int[] sortDNF(int[] tape) {
int smaller = 0; // everything with index < smaller is 0
int bigger = tape.length - 1; // everything with index > bigger is 2
int current = 0; // where we are looking now
int tmp;
while (current <= bigger) {
if (tape[current] == 0) {
tmp = tape[smaller];
tape[smaller] = tape[current];
tape[current] = tmp;
smaller++;
}
else if (tape[current] == 2) {
tmp = tape[bigger];
tape[bigger] = tape[current];
tape[current] = tmp;
bigger--;
}
current++;
}
return tape;
}
答案 4 :(得分:1)
您需要在检查1期间增加电流并检查2.当您检查3时,您只需要递减更大。这是工作解决方案。 BTW这适用于1-3之间的值数组。如果您愿意,可以将其更改为0-2。
程序产生以下输出,给定一个随机数组,如下所示:
原始数组:[1,3,3,3,2,2,2,1,2,2,1,3,3,2,1,1,3]
排序数组:[1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,3]
private static int[] sortUsingDutchNationalFlagProblem(int[] array)
{
System.out.println("Original Array : " + Arrays.toString(array));
int smaller = 0; // everything with index < smaller is 1
int bigger = array.length - 1; // everything with index > bigger is 3
int current = 0; // where we are looking now
int tmp;
while (current <= bigger) {
if (array[current] == 1) {
tmp = array[smaller];
array[smaller] = array[current];
array[current] = tmp;
smaller++;current++;
}
if(array[current] == 2)
current++;
if (array[current] == 3) {
tmp = array[bigger];
array[bigger] = array[current];
array[current] = tmp;
bigger--;
}
}
System.out.println("Sorted Array : " + Arrays.toString(array));
return array;
}
答案 5 :(得分:0)
这是我使用Java的方法
public static void dutchNationalFlagProblem(int[] input) {
int low=0, mid=0, high = input.length -1;
while(mid <=high) {
switch (input[mid]) {
case 0:
swap(input, low++, mid++);
break;
case 1:
mid++;
break;
default :
swap(input, mid, high--);
break;
}
}
}
private static void swap(int[] input, int firstIndex, int secondIndex) {
int temp = input[firstIndex];
input[firstIndex] = input[secondIndex];
input[secondIndex] = temp;
}
以下是相应的测试用例
@Test
public void dutchNationalFlagProblemTest() {
int[] input = new int[]{0,1,0,2,2,1};
ArrayUtils.dutchNationalFlagProblem(input);
assertThat(input, equalTo(new int[]{0,0,1,1,2,2}));
}
答案 6 :(得分:0)
下面的程序给出了正确的结果,你们看到这种简单的无害编程方法中的任何问题吗?
public class Test {
public static void main(String[] args) {
int arr[] = {1, 2, 0, 2, 1, 1, 1, 0, 0, 2, 2, 1, 0, 1, 2, 0, 2};
int x0 = 0, x1 = 0, x2 = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] == 0)
x0++;
if (arr[i] == 1)
x1++;
if (arr[i] == 2)
x2++;
}
int i = 0;
for (int j = i; j < x0; j++)
arr[i++] = 0;
for (int j = i; j < x0+x1; j++)
arr[i++] = 1;
for (int j = i; j < x0+x1+x2; j++)
arr[i++] = 2;
printArray(arr);
}
private static void printArray(int[] arr) {
for (int a : arr) {
System.out.print(a + " ");
}
}
}
答案 7 :(得分:-1)
我打算提出一个更简单的解决方案: - )
public static int[] sortDNF(int[] tape) {
Arrays.sort(tape);
return tape;
}
对于您的解决方案有什么问题,当前元素为2
并且它与列表末尾附近的元素交换时,与其交换的元素可能不 2,但你正在增加电流而不是再次看这个位置。