您的位置:首页 > 编程语言 > C语言/C++

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

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

思路分析:

可以维护两个指针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);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐