题目21 调整数组顺序使奇数位于偶数前面
题目描述:
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。
解题思路:
不考虑时间复杂度,最简单的思路是从头到尾扫描数组,每碰到一个偶数拿出这个数字,并把位于这个数字后面的所有数字往前挪动一位。挪动后数组末尾存在一个空位。这个时候把该偶数放入这个空位,由于碰到一个偶数需要移动O(n)个数字,因此总的时间复杂度是O(n^2)
代码实现:
package swordToOffer;
import java.util.Arrays;
public class Num21_ReorderNumArray {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] array = null;
System.out.println("原始数组:"+Arrays.toString(array));
ReOrder(array);
System.out.println("调整结果:"+Arrays.toString(array));
System.out.println();
int[] array2 = null;
System.out.println("原始数组:"+Arrays.toString(array2));
ReOrder(array2);
System.out.println("调整结果:"+Arrays.toString(array2));
System.out.println();
int[] array3 = {1,2,47,6,9,3};
System.out.println("原始数组:"+Arrays.toString(array3));
ReOrder(array3);
System.out.println("调整结果:"+Arrays.toString(array3));
System.out.println();
int[] array4 = {-5,2,3,6,-1,4,7};
System.out.println("原始数组:"+Arrays.toString(array4));
ReOrder(array4);
System.out.println("调整结果:"+Arrays.toString(array4));
System.out.println();
int[] array5 = {-1,1,2,1,3,-1,-2};
System.out.println("原始数组:"+Arrays.toString(array5));
ReOrder(array5);
System.out.println("调整结果:"+Arrays.toString(array5));
System.out.println();
int[] array6 = {1};
System.out.println("原始数组:"+Arrays.toString(array6));
ReOrder(array6);
System.out.println("调整结果:"+Arrays.toString(array6));
System.out.println();
}
//最简单的解答
public static void ReOrder(int[] array) {
if(array==null||array.length<=0) {
return;
}
int len = array.length;
int left = 0;
int right = len-1;
int temp;
while(left<right) {
//向后移动left指针,直到它指向偶数
while(left<len&&(array[left]&1)!=0) {
left++;
}
//向前移动right指针 直到它指向奇数
while(right>=0&&(array[right]&1)==0) {
right--;
}
if(left<right) {
temp = array[left];
array[left] = array[right];
array[right] = temp;
}
}
}
//扩展算法
public void ReOrder2(int[] array) {
if(array==null||array.length<=0) {
return;
}
int len = array.length;
int left = 0;
int right = len-1;
int temp;
while(left<right) {
//向后移动left指针,直到它指向偶数
while(left<len&&(isEven(array[left]))) {
left++;
}
//向前移动right指针 直到它指向奇数
while(right>=0&&(isEven(array[right]))) {
right--;
}
if(left<right) {
temp = array[left];
array[left] = array[right];
array[right] = temp;
}
}
}
public static boolean isEven(int n) {
return (n&1)==0;
}
}
扩展算法
如果题目改为把数组中的数按照大小分为两部分,所有负数都在非负数前面,该怎么做?
答:重新定义一个函数,在新的函数里面。只需要修改第二个和第三个while循环中的判断条件
如果把题目改成把数组中的数分为两部分,能够被三整除的数都在不能被三整除的数前面,怎么办?
答:再改while语句,
难道没有更好的办法吗?
考点收获:
- 判定一个数为偶数:a&1==0
- 判定一个数为偶数:a&1!=0