用于对 0、1 和 2 的数组进行排序的Java程序
给定一个由 0、1 和 2 组成的数组A[] 。任务是编写一个对给定数组进行排序的函数。这些函数应该把所有的 0 放在最前面,然后把所有的 1 和所有的 2 放在最后。
例子:
Input: {0, 1, 2, 0, 1, 2}
Output: {0, 0, 1, 1, 2, 2}
Input: {0, 1, 1, 0, 1, 2, 1, 2, 0, 0, 0, 1}
Output: {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2}
在这篇文章中讨论了一个简单的解决方案(对 0、1 和 2 的数组进行排序(简单计数))。
方法一:
方法:这个问题类似于我们的旧帖子 Segregate 0s and 1s in an array,这两个问题都是著名的荷兰国旗问题的变体。
问题是用三种颜色提出的,这里是“0”、“1”和“2”。该数组分为四个部分:
- a[1..Lo-1] 零(红色)
- a[Lo..Mid-1] 个(白色)
- a[Mid..Hi] 未知
- a[Hi+1..N] 双(蓝色)
- 如果第 i 个元素为 0,则将元素交换到低范围,从而缩小未知范围。
- 同样,如果元素为 1,则保持原样,但缩小未知范围。
- 如果元素为 2,则将其与高范围内的元素交换。
算法:
- 保持三个索引low = 1,mid = 1 和high = N,并且有四个范围,1到low(包含0的范围),low to mid(包含1的范围),mid to high(包含未知元素的范围)和高到 N(包含 2 的范围)。
- 从头到尾遍历数组,中间小于高。 (循环计数器为 i)
- 如果元素为 0,则将元素与索引低的元素交换并更新 low = low + 1 和 mid = mid + 1
- 如果元素为 1,则更新 mid = mid + 1
- 如果元素为 2,则将元素与索引高的元素交换,并更新 high = high – 1 并更新 i = i – 1。因为交换的元素未被处理
- 打印输出数组。
空跑:
在这个过程的一部分,一些红色、白色和蓝色元素是已知的,并且在“正确”的位置。未知元素部分 a[Mid..Hi] 通过检查 a[Mid] 被缩小:Examine a[Mid]. There are three possibilities:
a[Mid] is (0) red, (1) white or (2) blue.
Case (0) a[Mid] is red, swap a[Lo] and a[Mid]; Lo++; Mid++
Case (1) a[Mid] is white, Mid++
Case (2) a[Mid] is blue, swap a[Mid] and a[Hi]; Hi–
Continue until Mid>Hi.
执行:
Java
// Java program to sort an array // of 0, 1 and 2 import java.io.*; class countzot { // Sort the input array, the array // is assumed to have values in {0, 1, 2} static void sort012(int a[], int arr_size) { int lo = 0; int hi = arr_size - 1; int mid = 0, temp = 0; while (mid <= hi) { switch (a[mid]) { case 0: { temp = a[lo]; a[lo] = a[mid]; a[mid] = temp; lo++; mid++; break; } case 1: mid++; break; case 2: { temp = a[mid]; a[mid] = a[hi]; a[hi] = temp; hi--; break; } } } } /* Utility function to print array arr[] */ static void printArray(int arr[], int arr_size) { int i; for (i = 0; i < arr_size; i++) System.out.print(arr[i] + " "); System.out.println(""); } // Driver code public static void main(String[] args) { int arr[] = {0, 1, 1, 0, 1, 2, 1, 2, 0, 0, 0, 1}; int arr_size = arr.length; sort012(arr, arr_size); System.out.println( "Array after seggregation "); printArray(arr, arr_size); } } // This code is contributed by Devesh Agrawal
Java
// Java implementation of the approach import java.io.*; class GFG { // Utility function to print the // contents of an array static void printArr(int arr[], int n) { for (int i = 0; i < n; i++) System.out.print(arr[i] + " "); } // Function to sort the array of 0s, // 1s and 2s static void sortArr(int arr[], int n) { int i, cnt0 = 0, cnt1 = 0, cnt2 = 0; // Count the number of 0s, 1s and // 2s in the array for (i = 0; i < n; i++) { switch (arr[i]) { case 0: cnt0++; break; case 1: cnt1++; break; case 2: cnt2++; break; } } // Update the array i = 0; // Store all the 0s in the // beginning while (cnt0 > 0) { arr[i++] = 0; cnt0--; } // Then all the 1s while (cnt1 > 0) { arr[i++] = 1; cnt1--; } // Finally all the 2s while (cnt2 > 0) { arr[i++] = 2; cnt2--; } // Print the sorted array printArr(arr, n); } // Driver code public static void main(String[] args) { int arr[] = {0, 1, 1, 0, 1, 2, 1, 2, 0, 0, 0, 1}; int n = arr.length; sortArr(arr, n); } } // This code is contributed by shubhamsingh10
输出:
array after segregation 0 0 0 0 0 1 1 1 1 1 2 2
复杂性分析:
- 时间复杂度: O(n)。
只需要遍历一次数组。 - 空间复杂度: O(1)。
不需要额外的空间。方法二:
方法:计算给定数组中 0、1 和 2 的数量。然后将所有 0 存储在开头,然后存储所有 1,然后存储所有 2。
算法:
- 保持三个计数器 c0 计数 0,c1 计数 1,c2 计数 2
- 遍历数组,如果元素为0则增加c0的计数,如果元素为1则增加c1的计数,如果元素为2则增加c2的计数
- 现在再次遍历数组并用 0 替换第一个 c0 元素,用 1 替换下一个 c1 元素,用 2 替换下一个 c2 元素。
执行:
Java
// Java implementation of the approach import java.io.*; class GFG { // Utility function to print the // contents of an array static void printArr(int arr[], int n) { for (int i = 0; i < n; i++) System.out.print(arr[i] + " "); } // Function to sort the array of 0s, // 1s and 2s static void sortArr(int arr[], int n) { int i, cnt0 = 0, cnt1 = 0, cnt2 = 0; // Count the number of 0s, 1s and // 2s in the array for (i = 0; i < n; i++) { switch (arr[i]) { case 0: cnt0++; break; case 1: cnt1++; break; case 2: cnt2++; break; } } // Update the array i = 0; // Store all the 0s in the // beginning while (cnt0 > 0) { arr[i++] = 0; cnt0--; } // Then all the 1s while (cnt1 > 0) { arr[i++] = 1; cnt1--; } // Finally all the 2s while (cnt2 > 0) { arr[i++] = 2; cnt2--; } // Print the sorted array printArr(arr, n); } // Driver code public static void main(String[] args) { int arr[] = {0, 1, 1, 0, 1, 2, 1, 2, 0, 0, 0, 1}; int n = arr.length; sortArr(arr, n); } } // This code is contributed by shubhamsingh10
输出:
0 0 0 0 0 1 1 1 1 1 2 2
复杂性分析:
- 时间复杂度: O(n)。
只需要对数组进行两次遍历。 - 空间复杂度: O(1)。
因为不需要额外的空间。
有关详细信息,请参阅有关对 0、1 和 2 的数组进行排序的完整文章!
- 时间复杂度: O(n)。