有三个不同整数的排序数组,只经过一次传递
sorted array with three different integers with only one pass
是否有可能对三个整数的数组进行排序,仅对数组进行一次传递?
你:
int array[]={1,2,2,2,3,1,1,2,2,1,3}
,你被告知只有数字1、2、3
:
int array[]={1,1,1,1,2,2,2,2,2,3,3}
和不允许额外的空间
Tnx !
一行,不加空格:
第一个指针:表示数组2的起始点。
last指针:表示数组中第3的起始点。
如果找到1,将其与第一个指针交换。
如果你找到一个2,把它留在那里。
如果找到一个3,将它与最后一个指针交换。
排练:
{1,2,2,2,3,1,1,2,2,1,3} cur=1, first=1, last=10
{1,2,2,2,3,1,1,2,2,1,3} cur=2, first=2, last=10
{1,2,2,2,3,1,1,2,2,1,3} cur=3, first=2, last=10
{1,2,2,2,3,1,1,2,2,1,3} cur=4, first=2, last=10
{1,2,2,2,3,1,1,2,2,1,3} cur=5, first=2, last=10
{1,2,2,2,1,1,1,2,2,3,3} cur=5, first=2, last=9
{1,1,2,2,2,1,1,2,2,3,3} cur=5, first=3, last=9
{1,1,1,2,2,2,1,2,2,3,3} cur=6, first=4, last=9
{1,1,1,1,2,2,2,2,2,3,3} ...
时间:0 (n)(一次)
空间:O (1)
是的,使用计数排序。基本上,您遍历输入数组一次,并计算每个值出现的频率。之后,只需为每个bucket发出适当数量的值。
编辑:计数,不是桶排序。
这是一个直接的方法(不需要测试)
#include <iostream>
#include <algorithm>
#include <iterator>
void sort( int *first, int *last )
{
for ( int *current = first; current != last; )
{
if ( *current == 1 )
{
if ( current == first )
{
++current;
}
else
{
std::swap( *current, *first );
}
++first;
}
if ( *current == 3 )
{
--last;
if ( *current != *last ) std::swap( *current, *last );
}
if ( *current == 2 ) ++current;
}
}
int main()
{
int a[] = { 1, 2, 2, 2, 3, 1, 1, 2, 2, 1, 3 };
for ( int x : a ) std::cout << x << ' ';
std::cout << std::endl;
sort( std::begin( a ), std::end( a ) );
for ( int x : a ) std::cout << x << ' ';
std::cout << std::endl;
return 0;
}
输出为
1 2 2 2 3 1 1 2 2 1 3
1 1 1 1 2 2 2 2 2 3 3
这是e.w. Dijkstra在70年代早期描述的荷兰国旗问题的简单线性解决方案。它有时被用作快速排序的分区方法。
#include <iostream>
template <typename BidIt, typename T>
void dnf_partition(BidIt first, BidIt last, const T &pivot)
{
for (BidIt next = first; next != last;) {
if (*next < pivot) {
std::iter_swap(first++, next++);
} else if (pivot < *next) {
std::iter_swap(next, --last);
} else {
++next;
}
}
}
int main()
{
int array[] = { 1, 2, 2, 2, 3, 1, 1, 2, 2, 1, 3 };
for (int n : array) std::cout << n << ' ';
std::cout << 'n';
dnf_partition(std::begin(array), std::end(array), 2);
for (int n : array) std::cout << n << ' ';
std::cout << 'n';
}
ideone.com现场演示
是。对于计数排序,
int array[]={1,2,2,2,3,1,1,2,2,1,3};
int count[]={0,0,0};
int i = 0;
while (array[i] != ' ') {
count[array[i] - 1]++;
i++;
}
for (i = 0; i < count[0]; i++) {
printf("%i", 1);
printf(",");
}
for (i = 0; i < count[1]; i++) {
printf("%i", 2);
printf(",");
}
for (i = 0; i < count[2]; i++) {
printf("%i", 3);
if (i + 1 < count[2]) {
printf(",");
}
}
printf("n");
编辑
不允许有额外的空间
则没有。这是不可能的
相关文章:
- 我是否需要在下一次转移时将所有权*转移回转移队列
- 使用仅使用一次的变量调用的复制构造函数.这可能是通过调用move构造函数进行编译器优化的情况吗
- 在C++中一次将矢量值写入多个文件
- 循环中的条件:为什么每次都调用strlen(),而vector.size()只调用一次
- 为什么 zlib 放气初始化调用一次不起作用?
- 在一次迭代中从 txt 文件中读取多行
- 为什么无论你输入什么,这"while(cin.get(str,3))"只运行一次?
- 在头文件和 cpp 文件中使用一次 #pragma 时出现结构重定义错误
- 有没有办法一次声明相同类型的多个对象,并通过一个表达式立即使用相同的右值初始化它们?
- 高级选择排序 - 在一次迭代中搜索两个元素
- 具有相同特征的两个对象是否只在内存中存储一次?无论定义它们的函数是什么,都是不同的
- 如何仅使用一次固定<<设置精度(2)?或者至少恢复到默认行为?
- 什么是仅调用一次并调用参数的控制台应用
- 如何确保用户在一行上提示输入一次时输入名字和姓氏?
- (C++)虽然循环一次不起作用,但我引入了多个变量
- 为什么我的信号处理程序只执行一次?
- 如何使用C++一次读取整个二进制文件
- 花括号使循环运行一次?
- 从子菜单返回后,正确的输入至少进入验证循环一次
- 有三个不同整数的排序数组,只经过一次传递