题目描述:
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
思路分析:
本题的核心是排序结果的稳定性,所以优先想到冒泡排序以及归并排序的思想。
归并排序的思想就是将数组分为两段,第一段按照要求排好序,第二段按照要求排好序,然后再按照要求将两段拼接在一起。
拼接数组方式具体如下:
1,新建一个长度为两段数组长度之和的数组作为辅助数组。
2,新建两个指针1,2,分别指向两段数组的开始位置。
3,判定数组指针不能越界,并且第二段数组的开始位置不能是偶数。满足进入4,不满足进入5。
4,满足判定条件后,判断指针1的位置的值是否是奇数,如果是,则将该位置的值存入辅助数组,并将指针1向后移动一位;如果否,则将指针2所指的位置的值存入辅助数组,并将指针2向后移动一位。并返回3;
5,当跳出判断时,可能指针1越界,可能指针2越界,也有可能指针1,2指的都是偶数。因为不能改变相对位置,所以不论出现上述何种情况,都要先判断指针1是否越界,并将数组1剩余元素依次存入辅助数组中;接着判断指针2是否越界,并将数组2剩余元素依次存入辅助数组中。
6,将原数组中的元素依次替换成辅助数组中的元素即可。
代码如下:
public class Solution {
public void reOrderArray(int[] array) {
reOrderArr(array,0,array.length-1);
}
public void reOrderArr(int[] arr , int left, int right){
if(left >= right){
return;
}
int mid = left + ((right-left)>>1);
reOrderArr(arr,left,mid);
reOrderArr(arr,mid+1,right);
mergeSort(arr,left,mid,right);
}
public void mergeSort(int[] arr , int left , int mid , int right){
int l = left;
int r = mid+1;
int i = 0;
int[] temp = new int[right-left+1];
//将元素按照要求写入辅助数组中。
while(l<=mid && r<=right && arr[r]%2!=0){
temp[i++] = arr[l]%2 == 1 ? arr[l++] : arr[r++];
}
while(l<=mid){
temp[i++] = arr[l++];
}
while(r<=right){
temp[i++] = arr[r++];
}
//将辅助数组中的元素写入原数组中。
for( i =0 ; i < temp.length ; i++){
arr[left+i] = temp[i];
}
}
}
还有一种是冒泡排序的思想实现本题:
思路和冒泡排序的思路类似,就是换位的判断不一样,当指针指向的位置上的数值为偶数,并且下一个位置为奇数时才将两个位置上的数值交换。
public class Solution {
public void reOrderArray(int[] array) {
if(array == null || array.length < 2){
return ;
}
for(int i = 0 ; i < array.length ; i++){
for(int j = 0 ; j < array.length-1-i ; j++){
if(array[j]%2==0 && array[j+1]%2 != 0){
int temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
}
}
}
}
}