1. k 种颜色的荷兰国旗问题(中等):
将问题扩展到包含 k 种不同颜色(整数 0 到 k-1)的数组排序。这需要更通用的方法。
#include <stdio.h>
void dutch_flag_k(int arr[], int n, int k) {
int count[k];
for (int i = 0; i < k; i++) count[i] = 0;
for (int i = 0; i < n; i++) count[arr[i]]++;
int index = 0;
for (int i = 0; i < k; i++) {
for (int j = 0; j < count[i]; j++) {
arr[index++] = i;
}
}
}
int main() {
int arr[] = {2, 1, 0, 1, 2, 0, 1, 0, 2, 1, 2};
int n = sizeof(arr) / sizeof(arr[0]);
int k = 3; // 颜色数量
dutch_flag_k(arr, n,k);
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n"); // 输出:0 0 0 1 1 1 1 2 2 2 2
return 0;
}
2. 范围未知的荷兰国旗问题(困难):
事先不知道颜色的范围。你需要先找到最小值和最大值来确定颜色数量。然后,你可以使用类似于 k 种颜色版本的方法。
#include <stdio.h>
#include <limits.h>
int find_min_max(int arr[], int n, int *min, int *max) {
*min = INT_MAX;
*max = INT_MIN;
for (int i = 0; i < n; i++) {
if (arr[i] < *min) *min = arr[i];
if (arr[i] > *max) *max = arr[i];
}
return *max - *min + 1; // 颜色数量
}
void dutch_flag_unknown(int arr[], int n) {
int min, max;
int k = find_min_max(arr, n, &min, &max);
int count[k];
for (int i = 0; i < k; i++) count[i] = 0;
for (int i = 0; i < n; i++) count[arr[i] - min]++;
int index = 0;
for (int i = 0; i < k; i++) {
for (int j = 0; j < count[i]; j++) {
arr[index++] = i + min;
}
}
}
int main() {
int arr[] = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5};
int n = sizeof(arr) / sizeof(arr[0]);
dutch_flag_unknown(arr, n);
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n"); // 输出将根据找到的最小值和最大值进行排序。
return 0;
}
记住在运行之前使用 C 编译器(例如 GCC)编译这些代码。“范围未知”的版本需要仔细考虑内存使用和效率,因为它动态地确定颜色数量。