微博的一个编程题

BenWdev 2013-03-05 10:44:22
一个数组,比如A[]=[5,6,8,2,3,9,4],输出要求是所有的奇数在偶数的前面,并保留相对顺序。输出:[5,3,9,6,8,2,4]。要求:In-place (no additional place);时间复杂度:O(N)。
微博的 陈立人 传的 。
...全文
2495 48 打赏 收藏 转发到动态 举报
写回复
用AI写文章
48 条回复
切换为时间正序
请发表友善的回复…
发表回复
永不落伍 2013-04-28
  • 打赏
  • 举报
回复
哪个是正确的?我这个后辈也想学学
FancyMouse 2013-03-07
  • 打赏
  • 举报
回复
顺便你标红的O(n log * n)y time那个是previous work。
FancyMouse 2013-03-07
  • 打赏
  • 举报
回复
in-place学术惯例是指O(1)额外空间。严格0额外空间的算法至少我没见到过有人研究过。
ForestDB 2013-03-07
  • 打赏
  • 举报
回复
Abstract. In the stable 0-1 sorting problem the task is to sort an array of n elements with two distinct values such that equal elements retain their relative input order. Recently, Munro, Raman and Salowe gave an algorithm which solves this problem in O(n log * n)y time and constant extra space. We show that by a modication of their method the stable 0-1 sorting is possible in O(n) time and O(1) extra space. Stable three-way partitioning can be reduced to stable 0-1 sorting. This immediately yields a stable minimum space quicksort, which sorts multisets in asymptotically optimal time with high probability. 不晓得extra space能否满足in-place的要求?
一根烂笔头 2013-03-07
  • 打赏
  • 举报
回复
引用 40 楼 ForestDB 的回复:
那就是要排序,有见过O(n)的in-place排序么?
RT,不需要任何的辅助空间,估计两值交换都没法进行!应该是空间复杂度O(1)吧!多少还是需要个位数辅助空间的吧?
FancyMouse 2013-03-07
  • 打赏
  • 举报
回复
引用 42 楼 ForestDB 的回复:
对啊,题目还有stable的要求,即O(n)的in-place and stable的排序。
linear, stable, in-place => 我8L放的paper。
ForestDB 2013-03-07
  • 打赏
  • 举报
回复
对啊,题目还有stable的要求,即O(n)的in-place and stable的排序。
FancyMouse 2013-03-07
  • 打赏
  • 举报
回复
引用 40 楼 ForestDB 的回复:
那就是要排序,有见过O(n)的in-place排序么?
只是0-1排序。0-1排序本身的确可以线性做到。不要求stable的话楼上各种基于partition思想的代码都是正确的。
ForestDB 2013-03-07
  • 打赏
  • 举报
回复
那就是要排序,有见过O(n)的in-place排序么?
飞天御剑流 2013-03-07
  • 打赏
  • 举报
回复
不好意思,迟了点时间,因为dispatch元函数的构思伤点脑筋,昨晚没想出来,今天早上一起床,NND,就想出来了,呵呵。 总体思路是将分拆与合并从运行期移动到编译期,运行期的计算时间几乎为0,而且与输入规模无关,理论上支持无限个实参,实际运行要看编译器被蹂躏成啥样子了。 打印部分暂时没有提供,初步构思是从Tvector通过继承链定制一个动态类,再通过数值元函数的构造函数打印出来,今天没时间,写完再贴出来吧。 由于使用了可变参模板,请使用支持C++11的编译器。

=====main.cpp=====
#include <iostream>
#include "Sort.h"

typedef TypeVector< T<5>, T<6>, T<8>, T<2>, T<3>, T<9>, T<4> > Tvector; //容器构造5,6,8,2,3,9,4
typedef Sort< Tvector >::Result Result;  //Result就是重新排列后的结果

int main( void )
{
    ..........//打印Result的结果
    return 0;
}

============Sort.h============
#ifndef SORT_H_INCLUDED
#define SORT_H_INCLUDED

//结束符
struct TypeNone;

//类型选择元函数
template< bool, typename T, typename U >
struct If_Than;

template< typename T, typename U >
struct If_Than< true, T, U >
{
    typedef T Type;
};

template< typename T, typename U >
struct If_Than< false, T, U >
{
    typedef U Type;
};

//将数值转换为元函数
template< int N >
struct T
{
    enum { VALUE = N };
};

//类型序列容器定义
template< typename T1, typename T2 >
struct TypeList
{
    typedef T1 Head;
    typedef T2 Tail;
};

template< typename T0, typename... Tn >
struct TypeVector
{
    typedef TypeList< T0, typename TypeVector< Tn... >::Type > Type;
};

template< typename T0 >
struct TypeVector< T0 >
{
    typedef TypeList< T0, TypeNone > Type;
};

//push_front 你懂的
template< typename T, typename TList >
struct Push_Front
{
    typedef TypeList< T, TList > Type;
};

//将两个容器合并 你也懂的
template< typename TList1, typename TList2 >
struct Merge
{
    typedef TypeList< typename TList1::Head,
                      typename Merge< typename TList1::Tail, TList2 >::Type
                    > Type;
};

template< typename T, typename TList2 >
struct Merge< TypeList< T, TypeNone >, TList2 >
{
    typedef TypeList< T, TList2 > Type;
};

//分派元函数,将原来的容器分成奇数和偶数两个容器
template< typename TList >
struct Dispatch;

template< typename Head, typename Tail >
struct Dispatch< TypeList< Head, Tail > >
{
private :

    typedef Dispatch< Tail > Type;
    typedef typename Type::TypeOdd TypeOddTemp;
    typedef typename Type::TypeEven TypeEvenTemp;

public :

    typedef typename If_Than< Head::VALUE & 1,
                              typename Push_Front< Head, TypeOddTemp >::Type,
                              TypeOddTemp
                            >::Type TypeOdd;

    typedef typename If_Than< ! ( Head::VALUE & 1 ),
                              typename Push_Front< Head, TypeEvenTemp >::Type,
                              TypeEvenTemp
                            >::Type TypeEven;
};

template< >
struct Dispatch< TypeNone >
{
    typedef TypeNone TypeOdd;
    typedef TypeNone TypeEven;
};

//将分派和合并组合起来
template< typename Tvector >
struct Sort
{
private :

    typedef Dispatch< typename Tvector::Type > TListD;

public :

    typedef typename Merge< typename TListD::TypeOdd,
                            typename TListD::TypeEven
                          >::Type Result;
};

#endif // SORT_H_INCLUDED
FancyMouse 2013-03-07
  • 打赏
  • 举报
回复
引用 36 楼 ForestDB 的回复:
有点好奇,如果只是输出的话,遍历两遍,第一遍输出奇数,第二遍输出偶数,时间复杂度为O(2n),即O(n)。 LZ是不是少条件?
没有。因为in-place,指结果存放在原先的输入数组的地方。光printf不符合条件的。
飞天御剑流 2013-03-06
  • 打赏
  • 举报
回复
时间复杂度。
nice_cxf 2013-03-06
  • 打赏
  • 举报
回复
引用 26 楼 supermegaboy 的回复:
晚上给楼主写个时间复杂度O(1)的。
空间O(1)把?
飞天御剑流 2013-03-06
  • 打赏
  • 举报
回复
晚上给楼主写个时间复杂度O(1)的。
luzhengyue07 2013-03-06
  • 打赏
  • 举报
回复
感觉可以用类似冒泡法的方式,用一个指针指向已排好的序列的最后的位置,另一个指针向后移动,遇到奇数与第一偶数的位置调换。这样排完奇数的序列是保留的,偶数的序列发生变化,可以记录发生调换的次数再进行偶数数列的还原(根据调换次数从后向前将偶数与第一个偶数调换)。
Mourinho 2013-03-06
  • 打赏
  • 举报
回复
遍历2次数组即可,最坏时间复杂度O(2N) 用java写了个

package com.zyc.aaa;

public class Test10 {
	public static void main(String[] args) {
		int A[] = new int[] { 5, 6, 8, 2, 3, 9, 4 };
		printArr(A);
	}

	static void printArr(int[] arr) {
		int index = 0;
		for (int i = 0; i < arr.length; ++i) {
			if (arr[i] % 2 != 0)
				System.out.print(arr[i]);
			else
				arr[index++] = arr[i];
		}
		for (int i = 0; i < index; ++i)
			System.out.print(arr[i]);
	}
}

lxyppc 2013-03-06
  • 打赏
  • 举报
回复
这个代码完全没有移植性,只能算是一个奇技淫巧,而且不是我所原创,是某本书里面的
lxyppc 2013-03-06
  • 打赏
  • 举报
回复
题目说输出,没说要排序,可以用一个非主流,而且平台相关的办法 空间复杂度o(1),时间复杂度o(n)
void display_value(int arr[], int size)
{
    int i;
    for(i=0;i<size;i++){
        if(arr[i]&1)fprintf(stderr,"%d,",arr[i]);
        else fprintf(stdout,"%d,",arr[i]);
    }
}
这个代码在ubuntu上的运行結果,就是题目要求的
sniffer12345 2013-03-06
  • 打赏
  • 举报
回复
引用 34 楼 FancyMouse 的回复:
引用 22 楼 lxyppc 的回复:题目说输出,没说要排序,可以用一个非主流,而且平台相关的办法 空间复杂度o(1),时间复杂度o(n) C/C++ code?12345678void display_value(int arr[], int size){ int i; for(i=0;i<size;i++){ if(arr[i]&am……
我觉得这是最高好的办法
千树之影 2013-03-06
  • 打赏
  • 举报
回复
原数组可以看成一个奇数,偶数间隔排列的序列
加载更多回复(27)

70,012

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧