题目:输入一个整数数组。实现一个函数来调整该数组中数字的顺序。使得全部奇数位于数组的前半部分。全部偶数位于数组的后半部分。

1、基本实现:

假设不考虑时间复杂度,最简单的思路应该是从头扫描这个数组,每碰到一个偶数时,拿出这个数字,并把位于这个数字后面的全部的数字往前面挪动一位。

挪完之后在数组的末尾有一个空位。这时把该偶数放入这个空位。

因为没碰到一个偶数就须要移动O(n)个数字。因此总的时间复杂度是O(n2).可是,这样的方法不能让面试官惬意。只是假设我们在听到题目之后立就可以以说出这个解法,面试官至少会认为我们的思维很灵敏。


2、仅仅完毕基本功能的解法,仅适用于0基础程序猿

这个题目要求把奇数放在数组的前半部分。偶数放在数组的后半部分。因此全部的奇数应该位于偶数的前面,也就是说我们在扫描这个数组的时候,假设发现有偶数在奇数的前面,我们能够交换他们的数序,交换之后就符合要求了。

因此我们能够维护两个指针,第一个指针初始化时指向数组的第一个数字,它仅仅向后移动。第二个指针初始化时指向数组的最后一个数字。它指向前移动。在两个指针相遇之前,第一个指针总是位于第二个指针的前面。假设第一个指针的数字是偶数,而且第二个指针指向的数字是奇数,我们就交换两个数字。


3、考虑可扩展性的解法。秒杀Offer

假设是面试应届毕业生或者工作时间不长的程序猿。面试官会惬意前面的代码。但假设应聘者申请的是资深的开发职位。那面试官可能会接着问几个问题。

面试官:假设把题目改成数组中的数依照大小分为两部分,全部的负数在全部的非负数的前面,该怎么做?

假设再把题目改改,变成 把数组中的数分成两部分,能被3整除的数都在不能被3整除的数的前面。怎么办?

这就是面试官在考察我们对可扩展性的理解。即希望我们可以给出一个模式,在这个模式下可以非常方面第把已有的解决方式扩展到同类型的问题上去。

于是我们写出以下的代码:

/**
 * 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得全部奇数位于数组的前半部分,全部的偶数位于数组的后半部分
 */
package swordForOffer;

/**
 * @author JInShuangQi
 *
 * 2015年8月1日
 */
public class E14ReorderArray {
	public void order(int[] arr){
		if(arr == null)
			return;
		int i = 0;
		int j = arr.length-1;
		while(i<j){
			if(isEven(arr[i]) && !isEven(arr[j])){
				int temp = arr[i];
				arr[i]= arr[j];
				arr[j] = temp;
			}
			else if(!isEven(arr[i]) && isEven(arr[j])){
				i++;
			}
			else if(isEven(arr[i]) && isEven(arr[j])){
				j--;
			}else{
				i++;
				j--;
			}
		}
	}
	public boolean isEven(int n){
		return (n & 1) == 0;
	}
	public static void main(String[] args){
		E14ReorderArray test = new E14ReorderArray();
		int[] arr= {1,2,3,4,5,6,12,7,8,9,10};
		test.order(arr);
		for(int i = 0;i<arr.length ;i++){
			System.out.print(arr[i]+",");
		}
	}
}