题目:
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分。
分析:
数组的题目,调整位置需要移动元素,时间复杂度为O(n^2),因此通常需要另辟蹊径。
设定两个指针指向数组头尾,移动指针,达到判断条件时交换两个元素,直至两个指针相遇或交错。
小技巧:判断奇数偶数使用位与操作。
实现:
public void reOrder(int[] array) {
int len = array.length;
if (array == null || len <= 0)
return;
int start = 0;
int end = len - 1;
while (start < end) {
while ((start < end) && (array[start] & 1) == 1) {
start++;
}
while ((start < end) && (array[end] & 1) == 0) {
end--;
}
if (start < end) {
int temp = array[start];
array[start] = array[end];
array[end] = temp;
}
}
}
改进:
确保“排序”后数组中奇数和奇数,偶数和偶数之间的相对位置不变。
且修改上述程序,增强可扩展性,使之可适用于多个同类型题目。
实现:
public void reOrderArray(int[] array) {
if (array == null || array.length == 0)
return;
int i = 0, j;
while (i < array.length) {
// 从前先后,找到第一个偶数的位置i
while (i < array.length && !isEven(array[i]))
i++;
// 使第二个指针从第一个偶数的位置开始找后面第一个奇数位置j
j = i + 1;
while (j < array.length && isEven(array[j]))
j++;
if (j < array.length) {
// 将j处前的偶数都向后以后,空出第一个为偶数的位置i,放奇数
int temp = array[j];
for (int j2 = j - 1; j2 >= i; j2--) {
array[j2 + 1] = array[j2];
}
array[i++] = temp;
// 将i加1继续循环计算
} else {
// 查找失败,结束循环
break;
}
}
}
// 提取判断函数,实现可扩展性
boolean isEven(int n) {
if ((n & 1) == 0)
return true;
return false;
}