解题思路:
1.当遇到让将一个数组、字符串、字符数组划分成两部分的时候,可以考虑使用两个索引,i从数组的前面开始,j从数组的末尾开始,例如快排也是基于这种思想。针对本题,i从左边开始向右寻找到一个偶数,j从右边开始向左寻找到一个奇数,交换这两个索引对应的元素。继续重复上述操作,直到两个索引错开,则表明所有的奇数已经排在偶数的前面了。
2.当题目要求奇数和奇数的相对位置不变,偶数和偶数的相对位置不变时,上面的方法失效。这里有两种思路:(1)基于冒泡排序的思想,一旦遇到相邻两个数前面一个是偶数,后面一个是奇数,就交换。(2)利用空间换时间,额外开辟一个数组,长度和原数组相等,利用原数组统计其中奇数的个数,并在新数组中设置两个索引,一个指向奇数元素的开头,一个指向偶数元素的开头,遍历原数组,如果遇到奇数,则赋给新数组的奇数部分,否则赋给新数组的偶数部分。
/**
* 调整数组顺序使奇数位于偶数前面
*/
public class Solution {
/**
* 不考虑奇数和奇数间的相对位置,偶数和偶数间的相对位置
*
* @param array
*/
public void reOrderArray_withoutOrder(int[] array) {
if (array == null || array.length == 0) {
return;
}
// 因为需要使得奇数位于偶数前面,因此设置两个指针,p1从数组的头开始,专门用于指向偶数
// p2从数组的尾开始,专门用于指向奇数
int p1 = 0;
int p2 = array.length - 1;
while (p1 < p2) {
// p1从数组的最左边开始后移,直至找到一个偶数为止
while (array[p1] % 2 != 0) {
p1++;
}
// p2从数组的最右边开始前移,直至找到一个奇数为止
while (array[p2] % 2 == 0) {
p2--;
}
if (p1 < p2) {
// p1不可能等于p2,因为一个指向偶数,一个指向奇数
swap(array, p1, p2);
p1++;
p2--;
}
}
//当p1和p2错开后,表明所有奇数已经在偶数的前面
}
private void swap(int[] array, int p1, int p2) {
int temp= array[p1];
array[p1] = array[p2];
array[p2] = temp;
}
public void reOrderArray_RemainOrder(int[] array) {
//类似于冒泡排序思想
if(array == null || array.length == 0){
return;
}
Bubble_sort(array, array.length);
}
//一趟冒泡
public void bubble(int[] arr, int n) {
//一趟排序,将将离数组末尾最近的偶数移动到数组尾部
for (int i = 0 ; i < n - 1; i++) {
if (arr[i] %2 == 0 && arr[i+1] % 2 != 0) {
//如果前面一个是偶数,后面一个是奇数,则交换位置
swap(arr, i, i+1);
}
}
}
public void Bubble_sort(int[] arr, int n) {
while (n >= 1) {
bubble(arr, n);
n--;
}
}
//利用空间换时间
public void reOrderArray_RemainOrder1(int[] array) {
if(array == null || array.length == 0){
return;
}
int length = array.length;
//开辟一个数组
int[] temp = new int[length];
//统计原数组中奇数元素个数
int numOfOdd = 0;
for (int i = 0; i < array.length ; i++) {
if (array[i] % 2 != 0) {
//证明是奇数
numOfOdd++;
}
}
//在新数组中设置两个指针,一个指向奇数的起始位置,一个指向偶数的起始位置
//因为奇数在前,i指向奇数的起始位置
int i = 0;
int j = numOfOdd;
//利用原数组给新数组赋值
for (int k = 0; k < length; k++) {
if (array[k] % 2 != 0) {
//如果k指向的是奇数
temp[i] = array[k];
i++;
} else {
//如果k指向的是偶数
temp[j] = array[k];
j++;
}
}
//更新原数组中的值
for (int p = 0; p < length; p++) {
array[p] = temp[p];
}
}
}