剑指offer 面试题14:调整数组顺序使奇数位于偶数前面(C++版)

来源:互联网 发布:apriori算法例题 编辑:程序博客网 时间:2024/05/15 23:47

题目:输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有偶数位于数组的后半部分。

思路分析:

可以维护两个指针i和j,i指向数组的第一个数字,它只向后移动;j指向数组的最后一个数字,它只向前移动。在两个指针相遇之前,第一个指针总是位于第二个指针的前面。如果第一个指针指向的数字为偶数,并且第二个指针指向的数字是奇数,就交换这两个数字。当两个指针相遇时,表示所有的奇数都已经在偶数的前面了。

时间复杂度:O(n)

代码:

#include <iostream>#include <vector>using namespace std;vector<int> & func(vector<int> &a){vector<int> :: iterator i = a.begin();vector<int> :: iterator j = a.end() - 1;//end指向末尾元素的下一个位置while( i < j){while( i != j && (*i & 1) == 1 ){//奇数,向后移动i指针,直到它指向偶数i ++;}while( i != j && (*j & 1) == 0){//偶数,向前移动j指针,直到它指向奇数j --;}if( i < j){//交换两个指针int tmp = *i;*i = *j;*j = tmp;}}return a;}int main(){int a[] = {1, 2, 3, 4, 5, 6, 7};vector<int> my(begin(a), end(a));func(my);for (auto c : my){cout << c << " ";}cout << endl;return 0;}
可扩展性的结法:

如果我们要把上题改成,将数组中能被3整除的放在不能被3整除的数的前面,怎么办?

其实这是一个解决一系列同类型的问题的通用办法。

我们可以把整个逻辑框架抽象出来,而把判断的标准变成一个函数指针,也就是用一个单独的函数来判断数字是否符合标准。这样我们就把整个函数分解成两部分:一是判断数字是应该在数组的前半部分还是应该在数组的后半部分,二是拆分数组的操作。这样可提高代码的可重用性,可得下面的代码:

vector<int> & reorder(vector<int> &a, bool (*fun) (int) ){vector<int> :: iterator i = a.begin();vector<int> :: iterator j = a.end() - 1;//end指向末尾元素的下一个位置while( i < j){while( i != j && !fun(*i) ){//奇数,向后移动i指针,直到它指向偶数i ++;}while( i != j && func(*i) ){//偶数,向前移动j指针,直到它指向奇数j --;}if( i < j){//交换两个指针int tmp = *i;*i = *j;*j = tmp;}}return a;}bool isEven(int n){//判断是否为偶数return (n & 1) == 0;}void reorderOddEven(vector<int> &v){reorder(v, isEven);}




0 0
原创粉丝点击