将一个整数数组中的所有奇数放到偶数前面
如:
原始数组:{5,8,3,4,1,7,9,2,6,120}
最终结果:{5,3,1,7,9,2,4,6,120,8}
面试时面试官说出题目后,加了一句,需要最优时间复杂度。
我当时就有点懵,对时间复杂度不了解,于是第一想法就排除了双重循环,然后就想不出更好的解决办法了。
仔细分析这个题目:
寻找数组前面所有的偶数(能被2整除的数),放到数组后面;
寻找数组后面所有的奇数(不能被2整除的数),放到数组前面;
是不是从数组开头位置启动一个循环,每当遇到一个偶数时,再从数组末尾位置启动一个循环,寻找一个奇数,找到后调换两者的位置。
当两层循环的变量在k点相遇时,就证明:
数组k位置之前所有的数字都是奇数,数组k位置之后的所有数字都是偶数。
对我当时就是这个思路,逃不开双重循环。
如:
原始数组:{5,8,3,4,1,7,9,2,6,120}
最终结果:{5,3,1,7,9,2,4,6,120,8}
面试时面试官说出题目后,加了一句,需要最优时间复杂度。
我当时就有点懵,对时间复杂度不了解,于是第一想法就排除了双重循环,然后就想不出更好的解决办法了。
仔细分析这个题目:
寻找数组前面所有的偶数(能被2整除的数),放到数组后面;
寻找数组后面所有的奇数(不能被2整除的数),放到数组前面;
是不是从数组开头位置启动一个循环,每当遇到一个偶数时,再从数组末尾位置启动一个循环,寻找一个奇数,找到后调换两者的位置。
当两层循环的变量在k点相遇时,就证明:
数组k位置之前所有的数字都是奇数,数组k位置之后的所有数字都是偶数。
对我当时就是这个思路,逃不开双重循环。
有了思路,撸起代码就简单了,直接上代码吧,有注释:
public class Test {
public static void main(String[] args) {
int[] arr = {7, 8, 1, 4, 2, 5, 3, 10, 6, 13};
changeOddNumberAhead(arr);
print(arr);
}
/**
* change odd numbers to head of even numbers
*
* @param numArr
*/
private static void changeOddNumberAhead(int[] numArr) {
if (numArr == null || numArr.length <= 1) {
//数组为null,或者长度 <= 1,都不需要处理。
return;
}
//内层循环的变量,默认等于数组的最后位置
int innerIndex = numArr.length - 1;
//临时变量
int temp;
//开始循环整个数组,寻找偶数
for (int i = 0; i < numArr.length; i++) {
//循环停止条件
if (i >= innerIndex) {
//已经处理完毕了,返回
return;
}
if (numArr[i] % 2 != 0) {
//找到的是奇数
continue;
}
for (; innerIndex >= 0; innerIndex--) {
//循环停止条件
if (i >= innerIndex) {
//已经处理完毕了,返回
//内层循环也需要判断条件,不能循环到数组开头位置
return;
}
if (numArr[innerIndex] % 2 == 0) {
//找到的是偶数
continue;
}
//交换数组元素
temp = numArr[innerIndex];
numArr[innerIndex] = numArr[i];
numArr[i] = temp;
//每当成功调换一对元素后,需要break内层循环
//重新执行外层循环,寻找下一个偶数
//不要忘记这儿的break
break;
}
}
}
private static void print(int[] arr) {
if (arr == null || arr.length == 0) {
return;
}
StringBuilder stringBuffer = new StringBuilder();
for (int i = 0; i < arr.length; i++) {
stringBuffer.append(arr[i]);
if (i != arr.length - 1) {
stringBuffer.append(", ");
}
}
System.out.println(stringBuffer.toString());
}
}