百度笔试题:负数在前 正数在后(奇数在前,偶数在后)

百度面试题(一):假设一整型数组存在若干正数和负数,现在通过某种算法使得该数组的所有负数在正数的左边,且保证负数和正数间元素相对位置不变。时空复杂度要求分别为:o(n)o(1)。


百度面试题(二),给定一个存放正数的数组,重新排列数组使得数组左边为奇数,右边为偶数,且保证奇数和偶数之间元素相对位置不变。时空复杂度要求分别为:o(n)o(1)。


分析:以上两个面试题本质是一样的,就是要把某一类数据放在前面,另外一类放在后面,并且不打乱原始数据的相对位置,题目的要求比较苛刻,需要O(n)的时间复杂度,并且O(1)的空间复杂度。可以这样考虑,题目要求负数在前,正数在后,并且正负数相对位置不变,可以从后往前扫描(而不是从前往后扫描),使用两个指针,i指向下一个正数,j指向下一个交换的位置,i,j初始值均指向数组最后一个元素,从后往前开始扫描,如果当前值为正,就将两个指针所指向元素交换,这样一遍扫描就可以得到问题的解了,具体代码如下:

#include 
#include 

void swap(int &a, int &b ) // 交换
{
	int tmp = a;
	a = b;
	b = tmp;
}

void printArr( int arr[], int len ) // 输出数组
{
	for ( int i = 0; i < len; i++ )
	{
		printf("%d\t", arr[i]);
	}
	printf("\n");
}

void classSort( int arr[], int len ) // 排序
{
	int i = len -1; //  下一个正数
	int j = len -1; // 下一个需要交换的位置

	while ( i >= 0 ) // 从后往前扫描
	{
		if ( arr[i] > 0 ) // 当前值为正
		{
			swap( arr[i], arr[j] );
                        // 交换之后同时向前走
			--i;
			--j;
		}
		else // 当前值为负
		{
			--i; // 向前走
		}
	}
}

int main(int argc, char* argv[])
{
	int arr[] = { -5, -2, 3, 7, -1, 1, -4};
	int len = sizeof(arr) / sizeof(int);

	printf("before sort:\n");
	printArr(arr, len);

	// sort
	classSort(arr, len);

	printf("after sort:\n");
	printArr(arr, len);


	return 0;
}



// main output



// 好像有问题,这样只能保证正数相对位置不变,而负数相对位置有可能变化,考虑下面一组值int arr[] = { 2, -9, 6, -5, -2, 3, 7, -1, 1, -4};

// main output




// 不好意思,我再考虑考虑。。。。。。汗

你可能感兴趣的:(算法)