这是《编程访谈》一书中的一个问题: 题: 给定n个对象的数组,它们的键具有四个值,请对该数组重新排序,以使具有相同类型的对象一起出现。使用O(1)的额外空间和O(n)的时间。
我无法为三个以上的组构想一个主意(荷兰国旗问题)。任何帮助将不胜感激。
例如a [6] = {1,2,3,4,3,1};那么结果应该是{1,1,2,3,3,4}或以任何顺序排列,只有数字分组才有意义(即,结果不必按升序排列)
答案 0 :(得分:4)
要使具有相同颜色的标记组合在一起,我们可以使用一个指针变量,并将所有具有当前标记的元素交换到左侧,并对每个后续标记重复此操作。最后,我们将所有4个标志分组在一起。空间复杂度为O(1),时间复杂度为O(标志数* n)。由于您的案例的标记为4,因此它将为O(4 * n)= O(n)。
#include <iostream>
using namespace std;
int main() {
int a[] = {1,2,3,4,3,1,2,3,3,4};
int size = sizeof(a) / sizeof(int);
int ptr = 0;
for(int flag=1;flag <= 4;++flag){
for(int i=ptr;i<size;++i){
if(a[i] == flag){
swap(a[i],a[ptr++]);
}
}
}
for(int i=0;i<size;++i){
cout<<a[i]<<" ";
}
}
答案 1 :(得分:0)
O(n)DNF解从最低和最高索引开始形成两个集合,并且知道在它们之间某个地方形成的第三集合是同质的,因此不需要进一步处理。
如果将集合的数量增加到四个或更多,您仍然可以在同一“精神”中形成顶部和底部集合,因此在O(n)时间内,但是中间部分仍然混合在一起,它具有再次检查。这就是为什么它不再是“纯” O(n)的原因。
int a[] = { 1,2,3,4,3,1,2,3,3,4 };
int size = sizeof(a) / sizeof(int);
int bottom = 0, top = size - 1;
for (int bottomband = 1, topband = 4; topband > bottomband; bottomband++, topband--) {
int i = bottom;
while (i <= top) {
if (a[i] == bottomband) {
swap(a[i], a[bottom]);
i++;
bottom++;
}
else if (a[i] == topband) {
swap(a[i], a[top]);
top--;
}
else
i++;
}
}
for (int i = 0; i<size; ++i) {
cout << a[i] << " ";
}
您可以识别出内部的“经典” DNF循环(当topband
从3开始时,它就成为原始算法)。 a[]
来自其他解决方案,以实现可比性(例如将计数器放入内部循环等)。
答案 2 :(得分:0)
让 unik_elems 数组包含可以进行比较的不同元素。即我们可以将 <
或 >
与它们一起使用。例如[1,2,3,4]。
所以这里如果这些是 4 个不同的元素,那么我们可以首先选择主元为 2 并在 2 的左侧将 1 组,然后我们将主元更改为 3,将 2 组在 3 的左侧,因为我们已经分组了0,我们将获得未分组数组开始时的索引。这样我们就可以将主元更改为 4。假设我们首先对提供给我们的 4 个不同元素进行排序。
nums = [1,4,3,2,2,3,4,1,3,2,4,1,3,2,4,1]
unclassified = 0
unik_elems = [1,2,3,4]
for pivot_idx in range(1, len(unik_elems)):
pivot = unik_elems[pivot_idx]
# we start the array from the index from where the elements are unclassified.
# Hence, when selecting 3 as pivot in this example, the elements on the left
# of unclassified will be 1 and hence wont we touched when we use 3 as the pivot.
for idx in range(unclassified, len(nums)):
if nums[idx] < pivot:
nums[idx], nums[unclassified] = nums[unclassified], nums[idx]
unclassified += 1
时间复杂度 = O(N),因为我们有 4 个不同的元素,所以这将是 3 遍解决方案。