题目:输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。
——来源于《剑指offer》
- 解题思路:使用两个指针p1和p2分别指向数组的首元素和尾元素,然后p1依次向后移动,p2依次向前移动。直到p1指向第一个偶数,p2指向第一个奇数的时候,p1和p2位置的元素进行交换。
- 代码实现:
import java.util.*;
public class Solution {
public void reOrderArray(int[] array) {
int p1 = 0;
int p2 = array.length - 1;
while (p1 < p2) {
while (p1 < p2 && (array[p1] & 1) == 1) {
++p1;
}
while (p1 < p2 && (array[p2] & 1) == 0) {
--p2;
}
if (p1 < p2) {
array[p1] = array[p1] ^ array[p2];
array[p2] = array[p1] ^ array[p2];
array[p1] = array[p1] ^ array[p2];
}
}
}
public static void main(String[] args) {
int[] array = {1, 2, 3, 4, 5, 6};
new Solution().reOrderArray(array);
System.out.println(Arrays.toString(array));
}
}
- 拓展:可以利用java8的函数式接口对上面算法进行进一步封装使其能解决更多同类型问题,比如:
- 对数组中的数按照大小划分,负数在前,正数在后
- 对数组中的数按照能否被3整除划分,能被3整除的在前,不能被3整除的在后
import java.util.*;
import java.util.function.*;
public class Solution {
public void reOrderArray(int[] array, Predicate<Integer> predicate) {
int p1 = 0;
int p2 = array.length - 1;
while (p1 < p2) {
while (p1 < p2 && predicate.test(array[p1])) {
++p1;
}
while (p1 < p2 && !predicate.test(array[p2])) {
--p2;
}
if (p1 < p2) {
array[p1] = array[p1] ^ array[p2];
array[p2] = array[p1] ^ array[p2];
array[p1] = array[p1] ^ array[p2];
}
}
}
public static void main(String[] args) {
int[] array = {1, 2, 3, 4, 5, 6};
new Solution().reOrderArray(array, n -> (n & 1) == 1);
System.out.println(Arrays.toString(array));
}
}
拓展:输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
- 要求相对位置不变,可以只用插入排序的思想,从左到右找到第一个奇数,将其插入数组的第一个位置,然后找到第二个奇数,将其插入数组的第二个位置,以此类推。
- 代码实现
public class Solution {
public void reOrderArray(int[] array) {
int position = 0;
for (int i = 0; i < array.length; i++) {
if ((array[i] & 1) == 1) {
int temp = array[i];
int j = i;
while (j > position) {
array[j] = array[j - 1];
--j;
}
array[position] = temp;
++position;
}
}
}
}