- 面试题14
- 题目描述:
- 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
- 输入:
- 每个输入文件包含一组测试案例。
对于每个测试案例,第一行输入一个n,代表该数组中数字的个数。
接下来的一行输入n个整数。代表数组中的n个数。
- 输出:
- 对应每个测试案例,
输入一行n个数字,代表调整后的数组。注意,数字和数字之间用一个空格隔开,最后一个数字后面没有空格。
- 样例输入:
-
5 1 2 3 4 5
- 样例输出:
-
1 3 5 2 4 第一种解法:遍历。两重for循环。判断奇数偶数,然后交换位置。 第二种解法:使用两个指针分别指向首尾地址,然后从前向后找偶数,从后向前找奇数,交换位置(可以看做时快排)。符合书上要求,不符合这题(按原有顺序排列)。 如样例:按照书上思路求出的是 1 5 3 4 2; 书上:
/* *********************************************** Author :bo-jwolf Created Time :2015年02月11日 星期三 19:14:45 File Name :1516.cpp ************************************************ */ #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <math.h> #include <stdlib.h> #include <time.h> using namespace std; const int MAX = 1000005; int num[ MAX ], number[ MAX ]; int n; void Reorder( int *pData, int length, bool (*func)(int) ){ if( pData == NULL ?? length <= 0 ) return; int *pBegin = pData + 1; int *pEnd = pBegin + length; int i = 1, j = length; while( pBegin <= pData + length && i <= j &&func( *pBegin ) ){ number[ i++ ] = *pBegin; cout << *pBegin << endl; pBegin++; } while( pEnd >= pData + 1 && j > i && !func( *pEnd ) ){ number[ j-- ] = *pEnd; pEnd--; } } bool isEven( int n ){ // return (n & 1) == 0; return (n & 1 ) == 0; } void ReorderOddEven( int *pData, unsigned int length ){ Reorder( pData, length, isEven ); } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); while( scanf( "%d", &n ) != EOF ){ memset( num, 0, sizeof( num ) ); for( int i = 1; i <= n; ++i ){ scanf( "%d", &num[ i ] ); } ReorderOddEven( num, n ); for( int i = 1; i < n; ++i ){ printf( "%d ", number[ i ] ); } printf( "%d\n", number[ n ] ); } return 0; }
简化:
#include <vector> #include <cstdio> #include <iostream> using namespace std; int main() { //freopen("1516.input", "r", stdin); int n; vector<int> v; while (scanf("%d", &n) != EOF) { v.resize(n); for (int i = 0; i < n; ++i) { scanf("%d", &v[i]); } int s = 0, e = n - 1, t; while (s < e) { while ((v[s] & 1) && s < e) ++s; while (!(v[e] & 1) && s < e) --e; t = v[s]; v[s] = v[e]; v[e] = t; } for (int i = 0; i < n; ++i) { (i == n - 1) ? printf("%d\n", v[i]) : printf("%d ", v[i]); } } return 0; }
第三种解法:遍历一次,找到奇数则保留,找到偶数就插入到所以奇数长后面。有两种写法,(方案A)一种是可以使用临时数组,(方案B)一种则只能使用原有空间;
第一种写法(方案A):100ms
/* *********************************************** Author :bo-jwolf Created Time :2015年02月11日 星期三 20:24:56 File Name :1516a.cpp ************************************************ */ #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <math.h> #include <stdlib.h> #include <time.h> using namespace std; const int MAX = 100005; int num[ MAX ], number[ MAX ]; bool isOdd( int n ){ return ( n & 1 ) == 1; } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int n; while( scanf( "%d", &n ) != EOF ){ memset( number, 0, sizeof( number ) ); for( int i = 1; i <= n; ++i ) scanf( "%d", &num[ i ] ); int k1 = 1, k2 = n; for( int i = 1; i <= n; ++i ){ if( isOdd(num[ i ] ) ) number[ k1++ ] = num[ i ]; } for( int i = n; i >= 1; --i ){ if( !isOdd( num[ i ] ) ) number[ k2-- ] = num[ i ]; } for( int i = 1; i < n; ++i ){ printf( "%d ", number[ i ] ); } printf( "%d\n", number[ n ] ); } return 0; }
第二种写法(方案B):70ms
/* *********************************************** Author :bo-jwolf Created Time :2015年02月11日 星期三 20:24:56 File Name :1516a.cpp ************************************************ */ #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <math.h> #include <stdlib.h> #include <time.h> using namespace std; bool isOdd( int n ){ return ( n & 1 ) == 1; } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int n, temp; vector<int> V; queue< int > Q; while( scanf( "%d", &n ) != EOF ){ V.resize( n+1 ); V.clear(); for( int i = 1; i <= n; ++i ){ scanf( "%d", &V[ i ] ); } int t = 0; for( int i = 1; i <= n; ++i ){ if( isOdd(V[ i ] ) ) V[ i - t ] = V[ i ]; else{ t++; Q.push( V[ i ] ); } } for( int i = n - t+1; i <= n; ++i ){ V[ i ] = Q.front(); Q.pop(); } for( int i = 1; i < n; ++ i ){ printf( "%d ", V[ i ] ); } if( n ) printf( "%d\n",V[ n ] ); } return 0; }