题目:输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分:
基本思路:如果不考虑时间复杂度,最简单的思路应该是从头扫描这个数组,每碰到一个偶数时,拿出这个数字,并把位于这个数字后面的所有数字往前挪动一位。挪完之后在数组的末尾有一个空位,这时把该偶数放入这个空位。由于每碰到一个偶数就需要移动O(n)个数字,因此总的时间复杂度是O(n2)。
高效解法:借鉴快速排序的思想,通过设置两个指针来进行交换操作,从而减少移动次数,提高效率.
- 第一个指针初始化时指向数组的第一个数字,它只向后移动;
- 第二个指针初始化时指向数组的最后一个数字,它只向前移动。
- 在两个指针相遇之前,第一个指针总是位于第二个指针的前面。如果第一个指针指向的数字是偶数,并且第二个指针指向的数字是奇数,我们就交换这两个数字。
void ReorderOddEven(int[] arr)
{
int i=0,j=arr.length-1;
while(i<j)
{
while((i<j)&& (arr[i] & 0x1)!=0)
i++;
while(i<j && (arr[j] & 0x1)==0)
j--;
swap(arr,i,j);
}
}
void swap(int[] arr,int i,int j){
int k=arr[j];
arr[j]=arr[i];
arr[i]=k;
}
如果题目改成讲数组中按照大小分成两部分,所有负数在非负数前面,或者如果改成能被3整除的数都在不能被三整除的前面,改怎么办,这里将isEvent提取出来,这是个规则,便于扩展到同类型问题上
void ReorderOddEven(int[] arr)
{
int i=0,j=arr.length-1;
while(i<j)
{
while((i<j)&& isEvent(arr[i]))
i++;
while(i<j && isEvent(arr[j]))
j--;
swap(arr,i,j);
}
}
void swap(int[] arr,int i,int j){
int k=arr[j];
arr[j]=arr[i];
arr[i]=k;
}
private boolean isEvent(int n){
return (n&1)==0;
}
原文链接:http://blog.csdn.net/qq_22329521/article/details/53164858