剑指offer:调整数组顺序使奇数位于偶数前面

题目描述

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

解题思路

  1. 维护两个指针,一个从头开始另一个从尾部开始,交换两指针的奇偶数,指针相遇则停止。
int i=0;
int j=array.length-1;
while(i<j){
// 向后移动,直到它指向偶数
while(i<j&&array[i]%2==1){
i++;
}
// 向前移动,直到它指向奇数
while(i<j&&array[j]%2==0){
j--;
}
int temp=array[j];
array[j]=array[i];
array[i]=temp;
}

  1. 考虑可扩展的解法,将判断标准单独解耦出来,提高代码的重用性
int i=0;
int j=array.length-1;
while(i<j){
// 向后移动,直到它指满足标准
while(i<j && !func(array[i])){
i++;
}
// 向前移动,直到它指满足标准
while(i<j && func(array[j])){
j--;
}
int temp=array[j];
array[j]=array[i];
array[i]=temp;
}

考虑到扩展性是一个经验丰富的程序员必需要考虑到的事情,因为解耦可以提高代码的重用性,为功能扩展提供了便利。

题型扩展

输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。

解题思路

一旦需要保证相对位置不变,那么前面的方法都不满足条件了。

  1. 类似于插入排序,不使用额外空间,从头到尾遍历,如果是奇数,那就往前找一段连续的偶数,然后与该段偶数交换位置。时间复杂度接近O(n^2)
public class Solution {
public void reOrderArray(int [] array) {
for (int i=0; i<array.length; i++){
// 使用位与运算代替求余,判断是否为奇数
if ((array[i]&1)==1){
int temp = array[i];
int j = i - 1;
// 往前找一段偶数,保证顺序
while(j>=0 && (array[j]&1)==0){
array[j+1] = array[j];
j --;
}
// 该奇数与该段偶数交换
array[j + 1] = temp;
}
}
}
}

  1. 使用额外空间,新建一个数组先把原数组中的奇数push进去再把偶数push进去,然后用新数组数据覆盖原数组即可,时间复杂度O(n),空间复杂度为O(n)
public class Solution {
public void reOrderArray(int [] array) {
int[] arrayTemp = new int[array.length];
int index = 0;
for (int i: array){
if((i&1)==1)
arrayTemp[index++] = i;
}
for (int j: array){
if((j&1)==0)
arrayTemp[index++] = j;
}
for (int x=0; x<array.length; x++){
array[x] = arrayTemp[x];
}
}
}
posted @ 2018-01-10 08:33  小丑进场  阅读(554)  评论(0)    收藏  举报